{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances , FunctionalDependencies #-} {-# OPTIONS_GHC -Wall #-} ---------------------------------------------------------------------- -- | -- Module : Data.Repr -- Copyright : (c) Conal Elliott 2008 -- License : BSD3 -- -- Maintainer : conal@conal.net -- Stability : experimental -- -- Compute least upper bounds (lub / join) of two values -- -- This version uses associated types for HasRepr ---------------------------------------------------------------------- module Data.Repr (HasRepr(..), onRepr, onRepr2) where -- Reprs. TODO: find & use a simple, standard generic programming framework. -- | A data type representation, in terms of standard data types. -- Requires that @'unrepr' . 'repr' == 'id'@. class HasRepr t r | t -> r where repr :: t -> r -- ^ to representation unrepr :: r -> t -- ^ from representation -- | Apply a binary function on a repr onRepr :: (HasRepr a ra, HasRepr b rb) => (ra -> rb) -> (a -> b) onRepr h = unrepr . h . repr -- | Apply a binary function on a repr onRepr2 :: (HasRepr a ra, HasRepr b rb, HasRepr c rc) => (ra -> rb -> rc) -> (a -> b -> c) onRepr2 h a b = unrepr (h (repr a) (repr b)) -- Equivalently: -- -- onRepr2 h a = unrepr . h (repr a) . repr -- -- onRepr2 h a = onRepr (h (repr a)) -- -- onRepr2 h = onRepr . h . repr -- Some HasRepr instances instance HasRepr (Maybe a) (Either () a) where repr Nothing = (Left ()) repr (Just a) = (Right a) unrepr (Left ()) = Nothing unrepr (Right a) = (Just a) instance HasRepr [a] (Either () (a,[a])) where repr [] = (Left ()) repr (a:as) = (Right (a,as)) unrepr (Left ()) = [] unrepr (Right (a,as)) = (a:as) -- ...