3

Im trying to implement a function that can flatten a list of lists. only one layer deep. so if I called flatten [[3],[3, 5]] I would get [3,3,5]. this is my code:

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

I am getting an error "non exhaustive patterns in function flatten" when I call flatten [[3], [5]]

1
  • 4
    (++) is a prelude function. Commented Sep 16, 2016 at 0:25

4 Answers 4

10

There are two fundamental patterns to consider when processing a list. Any list must be either:

  • the empty list ([])
  • a cons cell (_:_)

Since concat acts upon a list-of-lists, we can break that second case down into two cases by pattern matching on the first element of the list, which must be either

  • the empty list ([]:_)
  • a cons cell ((_:_):_)1

Which gives us three patterns all together:

concat [] = ...
concat ([]:xss) = ...
concat ((x:xs):xss) = ...

See how every list-of-lists must match exactly one of those patterns?

Now, given that breakdown, see if you can implement concat only using x, xs, xss, :, [], and concat itself.


  1. note that (_:_):_ is a different pattern from _:_:_, which is more explictly written _:(_:_). The former is a pattern for a non-empty list at the head of a list of lists. The latter is a pattern for a list of at least two elements.
Sign up to request clarification or add additional context in comments.

Comments

3

Possible solution:

flatten [] = []
flatten ([]:vs) = flatten vs
flatten ((x:xs):vs) = x:flatten (xs:vs)

Comments

0

You are using incorrect patterns. [smth] matches list with one element, in your case:

[[]] - is list with one empty list [(x:xs)] - is list with one element - list (x:xs), which is not empty

So both cases matches single-element list. That's why function fails on [[3], [5]]

Obviously, you may wanted other two cases: empty ([]) and not empty list ((x:xs))

flatten :: [[a]] -> [a]
flatten [] = []
flatten (x:xs) 

Comments

0

You can implement it exactly the same way concat is implemented in Prelude:

flatten :: [[a]] -> [a]
flatten xs = foldr (++) [] xs

1 Comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.