2017-11-25 143 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