[Haskell-cafe] flatten a nested list

Stefan O'Rear stefanor at cox.net
Fri Dec 29 04:37:28 EST 2006


On Thu, Dec 28, 2006 at 11:56:58PM -0800, pphetra wrote:
> data Store a = E a | S [Store a]
>              deriving (Show)
> 
> flat :: [Store a] -> [a]
> flat [] = []
> flat ((E x):xs) = [x] ++ flat xs
> flat ((S x):xs) = flat x ++ flat xs
> 
> so
> *Main> flat [E 1, S[E 2, S[E 3, E 4], E 5]]
> [1,2,3,4,5]

Since this problem is fundimentally tied to Lisp's dynamic
typing, it is no suprise it can be done very easily using
Haskell's support for dynamic typing:

> import Data.Typeable

> data D = forall a. Typeable a => D a  deriving(Typeable)

> flat :: D -> [D]
> flat (D x) = maybe [D x] (>>= flat) (cast x)

To use: map (\ (D x) -> cast x) flat (D [D 1, D [D 2, D 3], D 4]) :: [Maybe Integer]

The 'D' defines an existantial type, which can hold a value
of any type subject to the Typeable constraint.

Typeable allows the typesafe cast function, which returns
Nothing if the types were different.

maybe and >>= are prelude functions used to make the definition
shorter; without them:

> flat (D x) = case (cast x) of Just xs -> concatMap flat xs
>                               Nothing -> [D x]


More information about the Haskell-Cafe mailing list