module Data.HSet ( HSet(..) , HGet(..) , Contains , hask ) where import Control.Monad.Reader import Data.HSet.TypeLevel #if !(MIN_VERSION_base(4, 8, 0)) import Control.Applicative #endif -- | Heterogeneous set (list) of elements with unique types. Usefull -- with MonadReader data HSet (elems :: [*]) where HSNil :: HSet '[] HSCons :: ('False ~ (Elem elem elems)) => elem -> HSet elems -> HSet (elem ': elems) class (i ~ (Index e els)) => HGet els e i where -- | Get any data from HSet for you hget :: HSet els -> e instance HGet (e ': els) e 'Z where hget (HSCons e _) = e instance (i ~ (Index e els), ('S i) ~ (Index e (e1 ': els)), HGet els e i) => HGet (e1 ': els) e ('S i) where hget (HSCons _ els) = hget els type Contains els e = HGet els e (Index e els) hask :: (MonadReader (HSet els) m, Contains els e) => m e hask = do h <- ask return $ hget h ---------------------------------------------------------------- -- Tests: if this is compilable then tests done trollface.jpg -- fun :: HSet '[Int, Double, Integer, Float] fun = HSCons 1 $ HSCons 2 $ HSCons 3 $ HSCons 4 $ HSNil funInt :: Int funInt = hget fun funDoube :: Double funDoube = hget fun funInteger :: Integer funInteger = hget fun funFloat :: Float funFloat = hget fun this :: (Double, Float) this = let h = (,) <$> hask <*> hask in runReader h fun