2017-11-25 154 views
-3

我得到了一個使用模式匹配定義的Haskell函數,但我不是很明白爲什麼它看起來像它的樣子。在safeTail函數中的Haskell模式匹配

safeTail (x : xs) = xs 

我不是特別明白在(x:xs),這是什麼意思?

+0

如果是這樣的功能的完整定義,我會已命名爲'unsafeTail'或'dangerousTail',因爲這將在空列表中崩潰。 – chi

+0

我得到了空列表的catchall,但決定不把它放在這裏,因爲這裏的重點是我不明白(x:xs)的語法而不是函數。 – Wandy

回答

1

那就是模式匹配。

函數safeTail的第一個參數是一些列表類型。如果參數是非空列表,則此模式匹配將成功並將x綁定到head元素,將xs綁定到列表的尾部。

如果您將空列表傳遞給safeTail,則模式匹配將失敗,並檢查其他模式(如果存在)。

2

考慮列表數據類型的類似定義。

data List a = Empty | Cons a (List a) -- (1) 

有兩個構造函數:一個用於創建一個空列表,另一個用於創建一個給定值和另一個列表的列表。

模式匹配通過將值與用於創建它的構造函數進行匹配來工作。

safeTail (Cons x xs) = xs -- (2) 

也就是說,如果safeTail被施加到使用Cons構造定義的值,則返回值是第二個參數Cons

在實際的代碼,這兩個類型構造ListEmpty數據構造被命名爲[]Cons構造被命名爲(:)

data [] a = [] | (:) a ([] a) 

其中的Haskell允許以特殊語法

data [a] = [] | a : [a] 

應用類型建築工[]的類型或類型變量被寫入可以通過包括[]內部的參數,和所述符號構造器(代替因爲它以:開頭)可以用作中綴運算符。

也就是說,可以編寫

safeTail ((:) x xs) = xs -- (3) 

safeTail (x : xs) = xs -- (4) 

與(2),(3),和(4)等效於上述(1)。

>>> safeTail ((:) 3 ((:) 2 ((:) 1 []))) 
[2,1] 
>>> safeTail (3:2:1:[]) 
[2,1] 
>>> safeTail [3,2,1] 
[2,1] 

爲了進一步簡化,Haskell中表示(x:[])[x](x:y:[])[x,y]作爲等

safeTail一個完整的定義也將一個空的list參數提供一個值:

safeTail [] = [] 

Maybe基於定義

safeTail :: [a] -> Maybe [a] 
safeTail [] = Nothing 
safeTail (x:xs) = Just xs 
+0

基於'Maybe'的定義實際上是一個'safeHead'而不是'safeTail' – 4castle