Justin M
Justin M

Reputation: 1065

Haskell 99 Problems #7: Prepend vs Append to List

This passes:

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 []) = []

This fails:

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 []) = []

Error is:

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)

The difference is ++ instead of :. I know the former appends, the latter prepends, but why doesn't : work in this case? I don't understand the error.

Upvotes: 1

Views: 557

Answers (1)

thefourtheye
thefourtheye

Reputation: 239473

Actually ++ is the concatenation operator, which expects both the operators to be a list in this particular case. Since flatten returns a list, ++ concatenates them happily.

But, : just prepends only one item to a list. Since flatten x in flatten x : flatten (List xs) returns a list, : throws this error.

Upvotes: 7

Related Questions