module Data.HSet
( HSet(..)
, HGet(..)
) where
import Control.Monad.Reader
import Data.HSet.TypeLevel
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
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
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