当前位置: 首页 > 工具软件 > Haskell > 使用案例 >

Haskell 语法基础

凌征
2023-12-01

本周读完了 Haskell 入门文档,这里做一下笔记。

一、变量类型

变量

与命令式语言不同,Haskell 同一作用域内变量值不可改变。

r = 5
r = 2 -- error: multiple declarations of r
复制代码

由于同一作用域变量值不可改变,所以变量定义可以是任意次序。

-- 如下的两种定义是等价的

-- A
y = x * 2
x = 3
 
-- B
x = 3
y = x * 2
复制代码

递归定义

-- 与命令式语言不同,如下的代码是递归定义变量,而不是变量加1

r = r + 1
复制代码

作用域,函数参数的作用域和函数定义的作用域不同(和其他语言类似)。

Prelude> let r = 0
Prelude> let area r = pi * r ^ 2 -- 调用时 r == 5 而不是等于 0
Prelude> area 5
78.53981633974483
复制代码

类型

布尔(Bool)

取值:True False

Prelude> 2 + 3 == 5
True
Prelude> 7 + 3 == 5
False
复制代码

运算符: < <= == >= >|| && not

Prelude> (3 < 8) && (False == False)
True
Prelude> not (5 * 2 == 10)
False
复制代码

不支持不同类型的比较

Prelude> 2 == True
<interactive>:1:0:
    No instance for (Num Bool)
      arising from the literal ‘2’ at <interactive>:1:0
    Possible fix: add an instance declaration for (Num Bool)
    In the first argument of ‘(==)’, namely ‘2’
    In the expression: 2 == True
    In an equation for ‘it’: it = 2 == True
复制代码

中缀表达式和前缀表达式

Prelude> 4 + 9 == 13
True
Prelude> (==) (4 + 9) 13
True

Prelude> (3 < 8) && (False == False)
True
Prelude> (&&) (6 <= 5) (1 == 1) 
False
复制代码

数字

  • Int: 整数,32位机器上范围 -2147483648 to 2147483647;
  • Integer:任意大小,会有性能开销;
  • Double:双精度浮点数。

字符和字符串

字符(Char):单引号;

Prelude> :t 'H'
'H' :: Char
复制代码

字符串(String/[Char]):双引号;

-- 实际上就是字符列表,String 是 [Char] 同义词

Prelude> :t "H"
"H" :: [Char]
复制代码

字符串拼接:++

Prelude> "H" ++ "H"
"HH"
复制代码

列表和元组

  • 列表元素必须是同类型;

  • 列表拼接::

    Prelude> let numbers = [1,2,3,4]
    Prelude> numbers
    [1,2,3,4]
    Prelude> 0:numbers
    [0,1,2,3,4]
    Prelude> 1:0:numbers
    [1,0,1,2,3,4]
    Prelude> 2:1:0:numbers
    [2,1,0,1,2,3,4]
    Prelude> 5:4:3:2:1:0:numbers
    [5,4,3,2,1,0,1,2,3,4]
    
    Prelude> "hey" == ['h','e','y']
    True
    Prelude> "hey" == 'h':'e':'y':[]
    True
    复制代码
  • 元组元素个数不可改变;

  • 元组元素无需同类型;

    (True, 1)
    ("Hello world", False)
    (4, 5, "Six", True, 'b')
    复制代码

二、条件语句

Haskell 的条件语句除了其他语言中的 if-else,还有 Guards 和 piece-wise definition 两种形式。

if / then / else

mySignum x =
if x < 0 
    then -1
    else if x > 0
        then 1
        else 0
复制代码

Guards

mySignum x
| x < 0     = -1
| x > 0     = 1
| otherwise = 0
复制代码

piece-wise definition

pts :: Int -> Int
pts 1 = 10
pts 2 = 6
pts 3 = 4
pts 4 = 3
pts 5 = 2
pts 6 = 1
pts _ = 0
复制代码

三、函数

Haskell 函数中,无论定义和调用,参数两边的括号可省略,括号仅用来组合表达式。

签名和定义

xor :: Bool -> Bool -> Bool
xor p q = (p || q) && not (p && q)
复制代码

调用

xor True False -- output: True
复制代码

四、输入输出

-- TODO:
复制代码

五、其他

注释

  • 单行注释 --

    x = 5     -- x is 5.
    y = 6     -- y is 6.
    -- z = 7  -- z is not defined.
    复制代码
  • 多行注释 {- ... -}

    answer = 2 * {-
      block comment, crossing lines and...
      -} 3 {- inline comment. -} * 7
    复制代码

GHCi 命令

  • :quit/:q:退出 GHCi;

    Prelude> :quit
    Leaving GHCi.
    复制代码
  • :load/:l:加载模块;

    Prelude> :load Varfun.hs
    [1 of 1] Compiling Main             ( Varfun.hs, interpreted )
    Ok, modules loaded: Main.
    复制代码
  • :reload/:r:重新加载模块;

    *Main> :reload
    Compiling Main             ( Varfun.hs, interpreted )
    Ok, modules loaded: Main.
    *Main>
    复制代码
  • :type/:t:判断变量类型;

    Prelude> :type True
    True :: Bool
    Prelude> :t 1
    1 :: Num p => p
    复制代码

源码文件

.hs 为后缀,例如:Varfun.hs。

转载于:https://juejin.im/post/5cdfba996fb9a07ecc4453e4

 类似资料: