Haskell列表的匹配模式

时间:2014-12-12 18:48:06

标签: haskell

我是Haskell的新手,几天前我决定学习它,感谢haskell wikibook。

此刻我正在阅读列表的匹配模式,但我无法理解列表的语法。

这是一个例子(来自wikibook):

doubleList :: [Integer] -> [Integer]
doubleList [] = []
doubleList (n:ns) = (2 * n) : doubleList ns

我不理解(n:ns)部分。我该怎么看?

3 个答案:

答案 0 :(得分:5)

你可以这样读:(head:tail),所以如果你有[1, 2, 3]并且你与(x:xs)匹配,那么x将绑定到第一个元素列表1xs将绑定到列表的其余部分,在本例中为[2, 3]

答案 1 :(得分:3)

(:)是类型为a->[a]->[a]的运算符。这意味着它需要一个项目和这些项目的列表,并返回相同项目的另一个列表。输出列表是通过在输入列表前添加输入项而形成的。

以下是如何使用它

1:[2,3]

将返回

[1,2,3]

因为(:)出现在定义的左侧,在您的情况下,您是模式匹配,并且运算符用于解构值,而不是构建它。

例如,如果我们有

func (first:rest) = ....

并像这样称呼它

func [1,2,3]

将分配以下值

first=1 --notice, this is type a
rest=[2,3] --notice, this is type [a]

答案 2 :(得分:2)

可能有助于您理解的另一个提示是查看列表数据类型的定义:

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

请注意,Haskell仅针对列表类型制定特殊语法规则,通常[]不是有效的构造函数。该定义等同于

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

其中

[] = Empty
(:) = Cons

您可以将此模式匹配为

doubleList :: List Int -> List Int
doubleList Empty = Empty
doubleList (Cons n ns) = Cons (2 * n) (doubleList ns)

如果使用中缀形式书写:

doubleList (n `Cons` ns) = (2 * n) `Cons` doubleList ns

所以现在希望你能看到两个定义之间的相似之处。 Haskell还提供了

的特殊语法规则
[1, 2, 3, 4] = 1:2:3:4:[]

因为前者更容易编写和阅读。实际上,只要代码中有[1, 2, 3, 4]这样的列表文字,编译器就会先将其转换为1:2:3:4:[],然后再将代码转换为可执行文件。