在Haskell中,“++”和“:”有什么区别?

4
我不理解这个--
Prelude> "hi"++"there"
"hithere"
Prelude> "hi":"there"

<interactive>:12:6:
    Couldn't match expected type `[Char]' with actual type `Char'
    Expected type: [[Char]]
      Actual type: [Char]
    In the second argument of `(:)', namely `"there"'
    In the expression: "hi" : "there"
Prelude> 

为什么这个操作不会返回"hithere"呢?
3个回答

12
类型。在GCHi中尝试以下内容:
Prelude> :t (:)
(:) :: a -> [a] -> [a]
Prelude. :t (++)
(++) :: [a] -> [a] -> [a]

谢谢你向我介绍:t - Micah
1
@Micah:另一个非常有用的指令是“:info”,它可以为您提供有关类型的大量信息。 - Lily Ballard

6
我明白了。第一个运算符需要是一个元素,而不是一个列表。
因此,如果我写成'h':"ithere",它将返回"hithere"

1
请不要将评论发布为答案。您可以添加评论。 - fuz
如果这是你问题的确切答案,你应该把它作为一个答案发布出来。但是这篇帖子并不是对你问题的答案,只是一条评论而已。 - fuz
8
我认为这篇文章可以被视为答案。 - sdcvvc
第一个操作数对于 : 是一个元素,对于 ++ 是一个列表,这就是区别所在,因此我认为这也是问题的答案。 - Tikhon Jelvis
“答案”:“第一个运算符必须是元素,而不是列表。” 不是对标题中问题的回答,而是对帖子中问题的回答。 - Viktor Mellgren

4

: 运算符是列表的构造函数之一。因此,"hello" 可以表示为 'h':'e':'l':'l':'o':[]。你可以想象列表被定义为:(这不是真正的Haskell语法)

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

:通过取一个元素和一个列表来构建一个列表。这就是为什么类型是a->[a]->[a]

++将多个列表连接起来,它是通过使用:作为基本操作定义的:

(++) :: [a] -> [a] -> [a]
(++) []     ys = ys
(++) (x:xs) ys = x : xs ++ ys

请注意,阻止这段代码成为真正的Haskell语法的唯一因素是[]。你确实可以有中缀数据构造器(例如Data.Ratio中的:%,它们必须以:开头,就像前缀数据构造器必须以大写字母开头一样),甚至可以有类型构造器(->就是这样一个中缀类型构造器)。 - Jedai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接