列表构造/连接的语法

时间:2011-04-13 12:45:38

标签: list haskell syntax

我现在只在Haskell工作了两天,并且想知道下面两个函数定义之间的区别是:

Prelude> let swap (x1:x2:xs) = x2:x1:xs
Prelude> swap [1..5]
[2,1,3,4,5]
Prelude> let swap' (x1:x2:xs) = [x2] ++ [x1] ++ xs
Prelude> swap' [1..5]
[2,1,3,4,5]

那是什么让x2:x1:xs与[x2] ++ [x1] ++ xs不同? 拜托,谢谢。

2 个答案:

答案 0 :(得分:30)

类型签名是一个很好的起点:

(:) :: a -> [a] -> [a]
(++) :: [a] -> [a] -> [a]

您可以使用ghci中的:type (:):type (++)找到这些内容。

从类型签名中可以看出,两者都用于生成列表。

:运算符用于构造列表(并将它们再次分开以进行模式匹配)。要制作列表[1,2,3],您只需使用1 : 2 : 3 : []进行构建即可。 :的第一个元素是要添加到列表前面的项目,第二个元素是列表(也是使用:构建的,或者是[]表示的空列表)。

++运算符是列表连接。它需要两个列表并将它们一起添加。 [1,2,3] ++ [4,5,6]是合法的,而1 ++ [1,2,3]则不合法。

答案 1 :(得分:5)

这与语法无关。 (:)和(++)只是不同的运算符。 (:)是一个构造函数,它从元素和另一个列表构造一个列表。 (++)创建一个新列表,它是两个列表的串联。因为(++)不是构造函数,所以不能在模式中使用它。

现在我们来到语法:符号

[x2]

您使用的是

的简写
x2:[]

所以你在第二个例子中真正做的是:

(x2:[]) ++ (x1:[]) ++ xs

因此,在构建列表时,你无法避免(:),它是最终的唯一方法。请注意,您必须构造中间列表才能使用(++)。