列表构造/连接的语法

问题描述

|| 我现在只在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,5]
也就是说,什么使x2:x1:xs与[x2] ++ [x1] ++ xs不同? 请,谢谢。     

解决方法

类型签名是一个很好的起点:
(:) :: a -> [a] -> [a]
(++) :: [a] -> [a] -> [a]
您可以在ghci中用
:type (:)
:type (++)
找到这些。 从类型签名中可以看到,两个都用于生成列表。
:
运算符用于构造列表(并再次将它们拆开以进行模式匹配)。要列出
[1,2,3]
,您只需用
1 : 2 : 3 : []
进行构建。
:
的第一个元素是要添加到列表前面的项目,第二个元素是列表(也由
:
建立或由
[]
表示的空列表)。
++
运算符是列表串联。它需要两个列表并将它们附加在一起。
[1,3] ++ [4,5,6]
是合法的,而
1 ++ [1,3]
不是。     ,这与语法无关。 (:)和(++)只是不同的运算符。 (:)是一个构造函数,它从一个元素和另一个列表构造一个列表。 (++)创建一个新列表,该列表是两个列表的串联。因为(++)不是构造函数,所以不能在模式中使用它。 现在我们来看语法:符号
[x2]
您使用的是
x2:[]
因此,您在第二个示例中所做的实际上是:
(x2:[]) ++ (x1:[]) ++ xs
因此,构造列表时,您无法避免(:),这是最终的唯一方法。请注意,必须构造中间列表才能使用(++)。