我现在只在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不同? 拜托,谢谢。
答案 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
因此,在构建列表时,你无法避免(:),它是最终的唯一方法。请注意,您必须构造中间列表才能使用(++)。