Haskell 99问题#7:Prepend vs Append to List

时间:2015-01-11 05:03:31

标签: list haskell

通过:

data Nested List a = Elem a | List [NestedList a]
flatten :: NestedList a -> [a]
flatten (Elem a) = [a]
flatten (List (x:xs)) = flatten x ++ flatten (List xs)
flatten (List []) = []

这失败了:

data NestedList a = Elem a | List [NestedList a]
flatten :: NestedList a -> [a]
flatten (Elem a) = [a]
flatten (List (x:xs)) = flatten x : flatten (List xs)
flatten (List []) = []

错误是:

Couldn't match expected type `a' with actual type `[a]'
  `a' is a rigid type variable bound by
      the type signature for flatten :: NestedList a -> [a]
      at 007.hs:2:12
Relevant bindings include
  xs :: [NestedList a] (bound at 007.hs:4:18)
  x :: NestedList a (bound at 007.hs:4:16)
  flatten :: NestedList a -> [a] (bound at 007.hs:3:1)
In the first argument of `(:)', namely `flatten x'
In the expression: flatten x : flatten (List xs)

差异为++而非:。我知道前者是附加的,后者是附加的,但为什么:在这种情况下不起作用?我不明白这个错误。

1 个答案:

答案 0 :(得分:7)

实际上++是连接运算符,它希望运算符在这种特定情况下都是一个列表。由于flatten会返回一个列表,++会很高兴地将它们连接起来。

但是,:只在列表中添加一个项目。由于flatten x中的flatten x : flatten (List xs)会返回一个列表,:会抛出此错误。