本周读完了 Haskell 入门文档,这里作一下笔记。express
与命令式语言不一样,Haskell 同一做用域内变量值不可改变。函数
r = 5
r = 2 -- error: multiple declarations of r
复制代码
因为同一做用域变量值不可改变,因此变量定义能够是任意次序。性能
-- 以下的两种定义是等价的
-- A
y = x * 2
x = 3
-- B
x = 3
y = x * 2
复制代码
递归定义ui
-- 与命令式语言不一样,以下的代码是递归定义变量,而不是变量加1
r = r + 1
复制代码
做用域,函数参数的做用域和函数定义的做用域不一样(和其余语言相似)。spa
Prelude> let r = 0
Prelude> let area r = pi * r ^ 2 -- 调用时 r == 5 而不是等于 0
Prelude> area 5
78.53981633974483
复制代码
取值:True
False
code
Prelude> 2 + 3 == 5
True
Prelude> 7 + 3 == 5
False
复制代码
运算符: <
<=
==
>=
>
;||
&&
not
递归
Prelude> (3 < 8) && (False == False)
True
Prelude> not (5 * 2 == 10)
False
复制代码
不支持不一样类型的比较ip
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 两种形式。
mySignum x =
if x < 0
then -1
else if x > 0
then 1
else 0
复制代码
mySignum x
| x < 0 = -1
| x > 0 = 1
| otherwise = 0
复制代码
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
复制代码
: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。