Since no one has given this, you can define a function that will smooth out lists of arbitrary depth using MultiParamTypeClasses. I actually did not find it useful, but I hope it could be considered an interesting hack. I got the idea from the implementation of the multivarian function of Oleg.
{-# LANGUAGE MultiParamTypeClasses, OverlappingInstances, FlexibleInstances #-} module Flatten where class Flatten io where flatten :: [i] -> [o] instance Flatten aa where flatten = id instance Flatten io => Flatten [i] o where flatten = concatMap flatten
Now, if you download it and run in ghci:
*Flatten> let g = [1..5] *Flatten> flatten g :: [Integer] [1,2,3,4,5] *Flatten> let h = [[1,2,3],[4,5]] *Flatten> flatten h :: [Integer] [1,2,3,4,5] *Flatten> let i = [[[1,2],[3]],[],[[4,5],[6]]] *Flatten> :ti i :: [[[Integer]]] *Flatten> flatten i :: [Integer] [1,2,3,4,5,6]
Note that it is usually necessary to provide an annotation of the result type, since otherwise ghc cannot determine where to stop recursively applying the flatten class flatten . If you use a function with a monomorphic type, which, however, is sufficient.
*Flatten> :t sum sum :: Num a => [a] -> a *Flatten> sum $ flatten g <interactive>:1:7: No instance for (Flatten Integer a0) arising from a use of `flatten' Possible fix: add an instance declaration for (Flatten Integer a0) In the second argument of `($)', namely `flatten g' In the expression: sum $ flatten g In an equation for `it': it = sum $ flatten g *Flatten> let sumInt = sum :: [Integer] -> Integer *Flatten> sumInt $ flatten g 15 *Flatten> sumInt $ flatten h 15