我得到了一个使用模式匹配定义的Haskell函数,但我并不真正理解为什么它看起来像是这样。
safeTail (x : xs) = xs
我对(x:xs)没有特别理解,这是什么意思?
答案 0 :(得分:2)
考虑列表数据类型的类似定义。
data List a = Empty | Cons a (List a) -- (1)
有两个构造函数:一个用于创建一个空列表,另一个用于创建给定值和另一个列表的列表。
模式匹配的工作原理是将值与用于创建它的构造函数进行匹配。
safeTail (Cons x xs) = xs -- (2)
也就是说,如果将safeTail
应用于使用Cons
构造函数定义的值,则返回值是Cons
的第二个参数。
在实际代码中,类型构造函数List
和Empty
数据构造函数都命名为[]
,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
的完整定义也会为空列表参数提供一个值:
safeTail [] = []
或基于Maybe
的定义
safeTail :: [a] -> Maybe [a]
safeTail [] = Nothing
safeTail (x:xs) = Just xs
答案 1 :(得分:1)
模式匹配。
函数safeTail
的第一个参数是一些列表类型。如果参数是非空列表,则此模式匹配将成功并将x
绑定到head元素并将xs
绑定到列表的尾部。
如果您将空列表传递给safeTail
,则模式匹配将失败,并且会检查其他模式(如果存在)。