{- | Module : Data.List.Indexed Description : A library providing length-indexed and element-indexed lists which sit somewhere between homogeneous and fully heterogeneous lists. Copyright : Copyright (c) 2014 Kenneth Foner Maintainer : kenneth.foner@gmail.com Stability : experimental Portability : non-portable This module re-exports the 'ConicList' and 'CountedList' types and functions to work with them. -} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE PolyKinds #-} module Data.List.Indexed ( heterogenize , homogenize , module Data.List.Indexed.Counted , module Data.List.Indexed.Conic ) where import Data.List.Indexed.Counted import Data.List.Indexed.Conic -- We can convert between them using cones and co-cones -- | Turn a 'CountedList' into a 'ConicList' by means of a function from some @a@ to an @(f t)@. heterogenize :: (a -> f t) -> CountedList n a -> ConicList f (Replicate n t) heterogenize _ CountedNil = ConicNil heterogenize f (x ::: xs) = f x :-: heterogenize f xs -- | Given a function to collapse any @(f t)@ into an @a@, turn a 'ConicList' into a 'CountedList'. homogenize :: (forall t. f t -> a) -> ConicList f ts -> CountedList (Length ts) a homogenize _ ConicNil = CountedNil homogenize f (x :-: xs) = f x ::: homogenize f xs