Reputation: 1065
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
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