Haskell常用數(shù)據(jù)形式與函數(shù)

Function

defineName param = f(param)
模式匹配(pattern matching)為不同的模式分別定義函數(shù)體州邢,注意匹配所有情況的模式應(yīng)寫到最后伐蒂,類似switch/case,但匹配的是結(jié)構(gòu)拆吆,關(guān)系具體內(nèi)容的是哨位(guard)聋迎。

某種意義上函數(shù)名后的參數(shù)判斷本身就是“模式匹配”,注意類型注解和模式匹配中的括號意味著元組和表達(dá)式
兩種情況枣耀,由于元組內(nèi)部被逗號分隔霉晕,容易分辨

defineName1 :: type1->type2
defineName1 a = f()
defineName1 x = f(x)
guard通過檢查參數(shù)的性質(zhì)是否為真(布爾判斷),契合模式匹配的多條件分支捞奕。模式與guard相似的地方是對內(nèi)容的判斷(模式的結(jié)構(gòu)包含內(nèi)容)牺堰,稍微不同的是guard能對參數(shù)組合后的內(nèi)容進(jìn)行判斷。
元組的模式匹配指將每個成員分別寫出來
列表中[]匹配空列表缝彬,可以用: 與 []匹配非空列表萌焰,x:xs將列表的頭部綁定為x,余下部分為xs谷浅。
x:y:[]相當(dāng)于[x,y]匹配長度固定的列表扒俯。
不能在列表的模式匹配中使用++,
as模式(as-pattern),允許按模式將一個值分隔成多個項一疯,同時仍保留對其整體的引用撼玄。
如all@(x:y)

Prelude> firstletter all@(x:y) = "The first letter of "++all++" is "++[x]
Prelude> firstletter ['a','c','d']
"The first letter of acd is a"

case

模式匹配是case表達(dá)式的語法糖,函數(shù)參數(shù)的模式匹配只能在定義函數(shù)時使用墩邀,而case表達(dá)式可用在任何地方掌猛,始終沒有匹配的模式,將會產(chǎn)生運行時錯誤眉睹,注意用空格縮進(jìn)荔茬。注意typeclass與pattern的差別。

case expression of pattern -> result
                   pattern -> result
                   pattern -> result
                  ...

where

函數(shù)where中定義的名字只對本函數(shù)可見竹海,不必?fù)?dān)心它會污染其它函數(shù)的命名空間慕蔚。如果要對不同的函數(shù)重復(fù)使用到同一名字,應(yīng)把它置于全局定義中斋配】嘴可以在where綁定中使用模式匹配和定義函數(shù)灌闺,但where中定義的名字不能在函數(shù)的其它模式訪問?,最后一個模式可見坏瞄,guard也可見桂对。

let

let表達(dá)式的格式為let <bindings> in <expressions>。綁定的名字僅對in部分可見鸠匀,本身是表達(dá)式一定有返回值蕉斜。let把綁定語句放前面,后跟表達(dá)式狮崩,與where相反蛛勉。(指where與其函數(shù)的整體)鹿寻。直接在GHCi中定義let可省略in睦柴,這樣名字的定義在整個會話中可見,由于沒有in也不會出現(xiàn)返回值毡熏。

Prelude> let havefun x y = [x..y]
Prelude> havefun 1 5
[1,2,3,4,5]
Prelude> let hadfun x y = [x..y] in hadfun 3 7
[3,4,5,6,7]
Prelude> hadfun

<interactive>:61:1: error:
    ? Variable not in scope: hadfun
    ? Perhaps you meant ‘havefun’ (line 58)

list (列表是單類型的)

  1. 字符串是一組字符組成的列表坦敌,"hello"是['h','e','l','l','o']的語法糖
  2. [1,2,3]是1:2:3:[]的語法糖
  3. 嵌套列表的元素同樣不能混合放置類型
    a. 拼接字符串 list ++ list(會遍歷第一個列表)
    b. 添加字符串 element : list
    c. 訪問元素 list(string) !! index
    d. 比較元素 <、 >痢法、 >=狱窘、<=、==财搁、 /=
    e. 邏輯符號 &&蘸炸、||、not
    f. 列表頭尾操作 head尖奔、tail搭儒、last、init (不要用到空列表[]上)
    g. 列表屬性 length返回長度提茁,null檢查是否為空淹禾,reverse反轉(zhuǎn)列表,maximum取最大元素茴扁,minimum取最小元素铃岔,sum與product返回和與積
    h. 截取操作,take number list 取出列表的前number個峭火,返回列表毁习;drop number list 返回刪除前number個的列表。element elem list判斷元素是否包含于列表
    i. 區(qū)間卖丸,[a,n*a..b], [a..b],[a,n*a..]纺且。cycle函數(shù)接受一個列表作為參數(shù)并返回一個無限列表;repeat函數(shù)接受一個值作為參數(shù)坯苹,返回一個僅包含該值的無限列表隆檀。replicate接受列表長度和復(fù)制的元素,takeWhile取一個謂詞和列表作為參數(shù),在元素符合謂詞時返回元素恐仑,一旦不符合條件就停止泉坐,返回結(jié)果列表,注意與filter的區(qū)別裳仆。
    j. odd 判斷一個數(shù)是否為奇數(shù)腕让,even判斷一個數(shù)是否為偶數(shù)
Prelude> take 7 (repeat 6)
[6,6,6,6,6,6,6]
Prelude> take 17 (cycle "yukipedia")
"yukipediayukipedi" 
Prelude> [0.1,0.2..1]
[0.1,0.2,0.30000000000000004,0.4000000000000001,0.5000000000000001,0.6000000000000001,0.7000000000000001,0.8,0.9,1.0]
Prelude> [1,(-2)..(-20)]
[1,-2,-5,-8,-11,-14,-17,-20]

list comprehension

[f(x,y)|x<-set,y<-set,predicate(x,y),let <bindins> in <expressions>]
列表推導(dǎo)式自然是產(chǎn)生列表的咯
分別演示了自定義length函數(shù)(每次元素滿足謂詞,執(zhí)行f)歧斟、取出大寫字符(處理字符串)纯丸、不拆開嵌套列表而去除奇數(shù)(始終返回列表)

Prelude> [x * y | x<-[1,2,3], y<-[10,12,14],x*y>20]
[24,28,30,36,42]
Prelude> length' xs = sum [1|_<-xs]
Prelude> length' [1..20]
20
Prelude> removeNonUppercase st = [c|c<-st,c `elem`['A'..'Z']]
Prelude> removeNonUppercase "yuKiPEdiA"
"KPEA"
Prelude> let nestList = [[2,3,4,5],[6,7,8,9],[10,11,12,13,14]]
Prelude> [[x|x<-nL,even x]|nL<-nestList]
[[2,4],[6,8],[10,12,14]]

tuple

元組是異構(gòu)的,并且長度固定静袖,由括號括起觉鼻,由逗號隔開 。長度為2的元組(序?qū)Χ映龋琾air)與長度為3的元組(三元組坠陈,triple)被視為不同的類型。進(jìn)一步捐康,兩個元組要類型相同仇矾,需要每一項的類型都彼此對應(yīng)。毫無疑問解总,每個元組都可能是個獨特的類型贮匕。正因為如此,允許單元素的list花枫,卻不允許單元素的tuple刻盐。單純用括號包含單元素,最終也只是作為表達(dá)式得到單元素乌昔∠毒危空元組類型為()。

  1. fst取一個序?qū)?/em>作為參數(shù)磕道,返回其首項供屉。snd返回其尾項。
  2. zip list list 返回交叉配對的一組序?qū)?/em>溺蕉。
Prelude> zip [1..] ["yukino","yui","hiki"]
[(1,"yukino"),(2,"yui"),(3,"hiki")]

接下來演示一個實際問題伶丐,求三條邊為1..10的整數(shù),和為24的直角三角形疯特。函數(shù)式一般思路:先去一個初始的集合并將其變形哗魂,隨后持續(xù)地利用過濾條件縮小計算范圍。

Prelude> let rightTriangles' = [(a,b,c)|c<-[1..10],a<-[1..c],b<-[a..c-1],a^2+b^2==c^2,a+b+c==24]
Prelude> rightTriangles' 
[(6,8,10)]

基本數(shù)據(jù)類型

a.Int為有界整數(shù)漓雅,Integer無界录别,效率低于Int
b.Float 單精點浮點數(shù)朽色,Double雙精點
c.Bool布爾值
d.Char 表示一個Unicode字符,一個字符由單引號括起组题,一組字符的列表即字符串
e.凡是類型首字母大寫葫男,()除外
f.Odering類型有GT,LT崔列,EQ三種值梢褐,分別表示大于,小于赵讯,等于
g.String是[Char]的別名

類型推斷

:t 命令接受任何合法的表達(dá)式盈咳,返回其類型。:: 讀作“它的類型為”边翼。 后面可能會有type constraint鱼响,一定會有參數(shù)類型,最后一個參數(shù)代表返回值讯私。
對函數(shù)而言可以“靜態(tài)類型檢查”諸如factorial1 :: Integer -> Integer factorial1 n = sum[1..n]限制輸入?yún)?shù)热押。
當(dāng)對判斷性質(zhì)的運算符西傀,如==斤寇,+,-拥褂,使用:t時娘锁,需要用(),如:t (==)。其實當(dāng)中綴函數(shù)要作為參數(shù)或者前綴函數(shù)調(diào)用時饺鹃,都需要用括號括起莫秆。可以中綴形式定義函數(shù)悔详,通過反引號镊屎。

Prelude> :t "yukipedia"
"yukipedia" :: [Char]
Prelude> factorial n = product [1..n]
Prelude> :t factorial 
factorial :: (Num a, Enum a) => a -> a
Prelude> :t head
head :: [a] -> a

類型注解(type annotation)

編譯器可以辨認(rèn)出大部分表達(dá)式的類型,但有時需要提示具體的類型茄螃。類型注解跟在表達(dá)式后面缝驳,通過 :: 分隔,顯式表達(dá)類型归苍。

Prelude> read "True"
*** Exception: Prelude.read: no parse
Prelude> read "True"||False
True
Prelude> [read "True",False]
[True,False]
Prelude> (read "True",False)
(*** Exception: Prelude.read: no parse
Prelude> read "True"::Bool
True
Prelude> read "True"::Int
*** Exception: Prelude.read: no parse

類型變量(type variable)

形如head函數(shù)的類型判斷中的a用狱,a可以是任何類型,使用類型變量的函數(shù)被稱為多態(tài)函數(shù)(polymorphic function)拼弃。命名上夏伊,類型變量可以使用多個字符,不過一般約定為單字符吻氧,如a,b,c,d...溺忧。另外不同字符的類型變量并非意味兩者表示的類型一定不同咏连。
=>左側(cè)叫做類型約束(type constraint),暫時認(rèn)為類型變量始終泛指,而類型約束提供了范圍
多態(tài)常量(polymorphic constant)指類型約束后 (typeclass a)=> a 這個函數(shù)輸入輸出沒有變化鲁森?所有的數(shù)都是多態(tài)常量

Prelude> :t 7.0
7.0 :: Fractional p => p
Prelude> :t 7
7 :: Num p => p

類型類(typeclass)

typeclass是一組函數(shù)的集合捻勉,type constraint => type variable->type variable->..->type variable,所有變量都有類型刀森,如果該類型是某typeclass的instance踱启,那么它必須實現(xiàn)該類型所描述的行為。typeclass是定義行為的接口研底。即instance(變量所屬的類型)具備執(zhí)行“描述的行為”的能力埠偿,typeclass為定義行為的接口
1.Eq類型類用于判可斷相等性的類型榜晦,它的實例必須實現(xiàn)==和/=兩個函數(shù)冠蒋。
2.Ord類型類用于可比較大小的類型
3.Show類型類的實例為可以表示為字符串的類型
4.Read類型類與Show相反,將字符串轉(zhuǎn)化為某類型
5.Enum類型類包含()乾胶、Bool抖剿、Char、Ordering识窿、Int斩郎、Integer、Float喻频、Double等類型(實例),可作為succ函數(shù)和pred函數(shù)的參數(shù)
6.Bounded類型類的實例類型可以通過maxBound和minBound得到其上限和下限缩宜,如果元組中的項的類型都屬于Bounded類型類的實例,那么這個元組也屬于Bounded的實例甥温。
7.Num類型類的實例類型為Int锻煌、Integer、Float姻蚓、Double等宋梧,只有屬于Show和Eq的實例類型,才可以成為Num類型類的實例
8.Floating類型類僅包含F(xiàn)loat和Double兩種浮點類型
9.Integeral僅與整數(shù)有關(guān)狰挡,實例類型為Int和Integer
a.所有標(biāo)準(zhǔn)類型都是Eq類的實例(除與輸入輸出相關(guān)的類型和函數(shù)之外)
b.除函數(shù)以外捂龄,以上所有類型都是Ord,Read圆兵,Show的實例
c.typeclass含有多個類型作為實例跺讯,一個類型可以作為多個typeclass的實例。一個類型必須在成為某typeclass的實例后殉农,才能成為另一個typeclas的實例

Prelude> :t fromIntegral 
fromIntegral :: (Integral a, Num b) => a -> b
Prelude> fromIntegral (3)+3.2
6.2
Prelude> 3 + 3.2
6.2
Prelude> (3 :: Int)+3.2

<interactive>:39:12: error:
    ? No instance for (Fractional Int) arising from the literal ‘3.2’
    ? In the second argument of ‘(+)’, namely ‘3.2’
      In the expression: (3 :: Int) + 3.2
      In an equation for ‘it’: it = (3 :: Int) + 3.2
Prelude> (3 :: Float)+3.2
6.2

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末刀脏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子超凳,更是在濱河造成了極大的恐慌愈污,老刑警劉巖耀态,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異暂雹,居然都是意外死亡首装,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門杭跪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仙逻,“玉大人,你說我怎么就攤上這事涧尿∠捣睿” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵姑廉,是天一觀的道長缺亮。 經(jīng)常有香客問我,道長桥言,這世上最難降的妖魔是什么萌踱? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮号阿,結(jié)果婚禮上并鸵,老公的妹妹穿的比我還像新娘。我一直安慰自己倦西,他們只是感情好能真,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著扰柠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪疼约。 梳的紋絲不亂的頭發(fā)上卤档,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機(jī)與錄音程剥,去河邊找鬼劝枣。 笑死,一個胖子當(dāng)著我的面吹牛织鲸,可吹牛的內(nèi)容都是我干的舔腾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼搂擦,長吁一口氣:“原來是場噩夢啊……” “哼稳诚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瀑踢,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤扳还,失蹤者是張志新(化名)和其女友劉穎才避,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體氨距,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡桑逝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了俏让。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片楞遏。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖首昔,靈堂內(nèi)的尸體忽然破棺而出橱健,到底是詐尸還是另有隱情,我是刑警寧澤沙廉,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布拘荡,位于F島的核電站,受9級特大地震影響撬陵,放射性物質(zhì)發(fā)生泄漏珊皿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一巨税、第九天 我趴在偏房一處隱蔽的房頂上張望蟋定。 院中可真熱鬧,春花似錦草添、人聲如沸驶兜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抄淑。三九已至,卻和暖如春驰后,著一層夾襖步出監(jiān)牢的瞬間肆资,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工灶芝, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留郑原,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓夜涕,卻偏偏與公主長得像犯犁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子女器,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,788評論 0 38
  • 《六項精進(jìn)》 大綱酸役,背誦1遍,共368遍 《 大學(xué)》誦讀1遍,共228遍 其他經(jīng)典 活法 日行一善簇捍,完成 日省一事...
    a92bbf37be2b閱讀 165評論 0 0
  • 《大三小三》 隔壁家的孩子大三畢業(yè)了又去當(dāng)了小三 《怦然心動》 要不是你說“我們”我不會怦然心動 《重量級》 記住...
    何鯨洛閱讀 247評論 0 1
  • 我是從十萬傷心的大山里走來的人 我扛著黑色的鋤頭 帶著辛勤的思念 我一點點在愛你的路上耕耘 我在耕耘的時候背后被人...
    梵夜閱讀 196評論 0 4
  • 瑣事記8.6 前幾天只壳,母親熱得難受,晚上睡不著暑塑,她對我說吼句,想要裝個空調(diào)。我說事格,好的惕艳,我來支付空調(diào)的的費用。 第二天...
    小棕櫚閱讀 296評論 0 0