How to flatten a list of lists of lists in haskell

Billy Grande picture Billy Grande · Mar 17, 2014 · Viewed 13.4k times · Source

All I want to do is what I ask. The type signature of the function should be this:

flatten::[[[Int]]] -> [[Int]]

I tried to search some flatten code but they define new types and that confuses me. Any help? Thanks in advance.

Answer

chi picture chi · Mar 17, 2014

There are (at least) two ways to write

flatten::[[[Int]]] -> [[Int]]

One is

flatten1 = concat
-- Example: flatten [[[1], [2]], [[3]]] = [[1], [2], [3]] :: [[Int]]

Another one is

flatten2 = map concat
-- Example: flatten [[[1], [2]], [[3]]] = [[1,2], [3]] :: [[Int]]

Basically, flatten1 flattens the "middle" level of brackets, while flatten2 flattens the "innermost" level of brackets.

As an exercise, you might want to convince yourself that

concat . flatten1 = concat . flatten2 :: [[[Int]]] -> [Int]

Indeed, both would produce [1,2,3] on the example above.

A more advanced remark

The law above is actually a very famous one, since it is a special case of the monad law

join . fmap join = join . join :: Monad m => m (m (m a)) -> m a

where m = [] (i.e., in the list monad), and a=Int