Haskell 筆記 (二)基本知識

基本知識

邏輯運算符

邏輯 運算符
布爾值 Ture, False
邏輯與 &&
邏輯或
邏輯非 not
相等,不相等 ==, /=

函數

前綴函數(prefix function):大多數爲前綴函數,調用時格式爲:先是函數名,後跟參數列表,中間都是空格分開, 如: min 8 2
中綴函數(infix function): *就是中綴函數,夾在兩個參數中間。

通過’'可以將前綴函數,轉換爲中綴函數:

//前綴形式
ghci> div 80 16

等價爲:

//中綴形式
ghci> 80 'div' 16

列表

列表運算符

運算符 功能 例子
++ 拼接兩個列表 [1, 3, 5] ++ [6]=>[1, 3, 5, 6]
: 將元素插入表頭 [1] : [2, 3, 5, 6] => [1, 2, 3, 5, 6]
!! 訪問列表中元素, 下標從0開始 [1, 3, 5] !! 1 => 3
<,>,<=,>= 比較兩個列表大小 [3, 2, 1] > [2, 1, 0]=>True

列表函數

函數 功能 例子
head 返回列表的頭部,也就是第一個元素 head [5, 4, 3, 2, 1]=>5
tail 返回列表的尾部,也就是除了頭部之後的部分 tail [5, 4, 3, 2, 1]=>[4, 3, 2, 1]
last 返回列表的最後一個元素 last [5, 4, 3, 2, 1]=>1
init 返回列表除了最後一個元素的部分 init [5, 4, 3, 2, 1]=>[5, 4, 3, 2]
length 返回列表的長度 length [5, 4, 3, 2, 1]=>5
null 檢查列表是否爲空 null [5, 4, 3, 2, 1]=>False
reverse 反轉列表 reverse [5, 4, 3, 2, 1]=>[1, 2, 3, 4, 5]
take 返回指定列表的前幾個元素 take 2 [5, 4, 3, 2, 1]=>[5, 4]
drop 刪除指定列表的前幾個元素 drop 2 [5, 4, 3, 2, 1]=>[3, 2, 1]
maxinum 返回列表的最大的元素 maxinum [5, 4, 3, 2, 1]=>5
mininum 返回列表的最小的元素 mininum [5, 4, 3, 2, 1]=>1
sum 返回列表的所有元素的和 sum [5, 4, 3, 2, 1]=>15
product 返回列表的所有元素的積 product [5, 4, 3, 2, 1]=>120
elem 判斷一個元素是否在列表中 elem 4 [5, 4, 3, 2, 1]=>True

區間

通過區間可以構造列表,其中的值必須是可枚舉的,或者說,是可以排序的。

Prelude> [1..20]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
Prelude> ['a'..'z']
"abcdefghijklmnopqrstuvwxyz"
Prelude> ['K'..'Z']
"KLMNOPQRSTUVWXYZ"
Prelude>

區間可以調整步長

Prelude> [2, 4..20]
[2,4,6,8,10,12,14,16,18,20]
Prelude> [3, 6..20]
[3,6,9,12,15,18]

爲什麼[2, 2…20]不行?

Prelude> [2,2..20]
[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,22,2,2,2,2,2...

步長不是第一個數,而是通過第二個數減去第一個數計算出來的。
[2,2…20]:2-2=0, 步長成了0,一直不會到20,所以結束不了。

[20…1] 爲什麼爲空?

ghci>[20..1]
[]

[20…1]沒有提供步長,Haskell會默認構造一個空的列表,隨後從區間的下限開始,不停的增長等於上限爲止,20已經大於1了,所以是空。

也就是說步長默認是+1的,如果是-1,必須提供步長,[20,19…1]

ghci>[20,19..1]
[20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1]

如果不表明區間上限,將得到一個無限長度列表

ghci>[20,19..]
[20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-24,-25,-26,-27,-28,-29,-30,-31,-32,-33,-34,-35,-36,-37,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59,-60,-61,-62,-63,-64,-65,-66,-67,-68,-69,-70,-71,-72,-73,-74,-75,-76,-77,-78,-79,-80,-81,-82,-83,-84,-85,-86......

可以通過take取前幾個

ghci>take 10 [20,19..]
[20,19,18,17,16,15,14,13,12,11]

另外幾種生成無限列表的函數:

  1. cycle 函數: 接受一個列表作爲參數,並返回一個無限列表
ghci>take 10 (cycle [1, 2, 3])
[1,2,3,1,2,3,1,2,3,1]
ghci>take 14 (cycle "LOL ")
"LOL LOL LOL LO"
  1. repeate 函數: 接受一個值作爲參數,並返回一個無限列表
ghci>take 10 (repeat 6)
[6,6,6,6,6,6,6,6,6,6]
  1. replicate 函數: 一個參數表示列表的長度,一個參數表示要複製的值。
ghci>replicate 10 6
[6,6,6,6,6,6,6,6,6,6]

由於浮點數只能實現有限精度,最好不要在區間中使用浮點數。

ghci>[0.1, 0.2..1]
[0.1,0.2,0.30000000000000004,0.4,0.5,0.6,0.7000000000000001,0.8,0.9,1.0]
ghci>[0.1, 0.3..1]
[0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999]

列表推導式

列表推導式是一種過濾,轉換或者組合列表的方法

ghci> [x*2 | x <- [1..10]]
[2,4,6,8,10,12,14,16,18,20]

“|” 後 x <- [1…10] : x綁定1-10每個元素

“|” 前 x*2 : 輸出

還可以對綁定值增加過濾,形式爲[輸出 | 綁定,過濾],

如[x*2 | x <- [1…10], x > 12]

ghci> [x*2 | x <- [1..10], x*2 > 12]
[14,16,18,20]
ghci> [x*2 | x <- [1..10], x > 6]
[14,16,18,20]

將推導式設置爲函數, xs是列表,綁定到x,對其中x爲奇數的執行“ if x < 10 then “BOOM!” else “BANG!” ”

x <- xs, odd x 使x綁定到 7, 9, 11, 13

ghci> boomBangs xs = [ if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]
ghci> boomBangs [7..13]
["BOOM!","BOOM!","BANG!","BANG!"]

多個列表,結果是多個表元素的組合情況

ghci> [x + y | x <- [1..5], y <- [10, 100, 1000]]
[11,101,1001,12,102,1002,13,103,1003,14,104,1004,15,105,1005]
ghci> [x * y | x <- [1..5], y <- [10, 100, 1000]]
[10,100,1000,20,200,2000,30,300,3000,40,400,4000,50,500,5000]

元組

元組: 將多個異構的值合成爲一個單一值。長度固定。

長度爲2的元組叫做序對(pair)
長度爲3的元組叫做三元組(triple)

序對的操作:

  1. fst : 返回首項
  2. snd : 返回尾項
  3. zip : 通過2個列表生成序對, 2個列表不一樣長時,以短的爲準。

例題:
使用Haskell找出滿足下列條件的三角形

  • 三個表都爲整數
  • 三個邊長度都小於等於10
  • 周長爲24的三角形
ghci> [(x,y,z) | x<-[1..10], y<-[1..10], z<-[1..10], x*x + y*y ==z*z, x+y+z==24]
[(6,8,10),(8,6,10)]

解題思路:先初始化集合將其變形,在通過過濾條件縮小計算範圍。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章