本週讀完了 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。