我是Haskell的新手,几天前我决定学习它,感谢haskell wikibook。
此刻我正在阅读列表的匹配模式,但我无法理解列表的语法。
这是一个例子(来自wikibook):
doubleList :: [Integer] -> [Integer]
doubleList [] = []
doubleList (n:ns) = (2 * n) : doubleList ns
我不理解(n:ns)
部分。我该怎么看?
答案 0 :(得分:5)
你可以这样读:(head:tail)
,所以如果你有[1, 2, 3]
并且你与(x:xs)
匹配,那么x
将绑定到第一个元素列表1
和xs
将绑定到列表的其余部分,在本例中为[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:[]
,然后再将代码转换为可执行文件。