{-# LANGUAGE ExistentialQuantification
, ScopedTypeVariables
, TypeOperators
, ConstraintKinds
, MultiParamTypeClasses
, FlexibleInstances
-- , KindSignatures
, PolyKinds
#-}
module Data.HtsCSet ( HtsCSet
, empty, emptyP, singleton, singletonP
, null, size, member, notMember
, insert
, lookup, lookupWithDefault
, update
, existTypeOf, existTypeOfP
, (:+) (..), Append (..), fill
) where
import qualified Data.Map as M
import Data.Typeable
import GHC.Exts (Constraint)
import Prelude hiding (lookup, null)
data CastBox c = forall a. (Typeable a, c a) => CastBox { unBox :: a }
newtype HtsCSet c = HtsCSet { unHS :: M.Map TypeRep (CastBox c) }
data P a = P
mapCastBox :: forall c a. (Typeable a, c a) => (a -> a) -> CastBox c -> CastBox c
mapCastBox f o@(CastBox e) = case cast e of
(Just e') -> CastBox (f e')
Nothing -> o
empty :: HtsCSet c
empty = HtsCSet M.empty
emptyP :: proxy c -> HtsCSet c
emptyP _ = empty
singleton :: forall c a. (Typeable a, c a) => a -> HtsCSet c
singleton a = HtsCSet (M.singleton (typeRep (Proxy :: Proxy a)) (CastBox a))
singletonP :: forall proxy c a. (Typeable a, c a) => proxy c -> a -> HtsCSet c
singletonP _ = singleton
null :: HtsCSet c -> Bool
null = M.null . unHS
size :: HtsCSet c -> Int
size = M.size . unHS
member :: forall proxy c a. Typeable a => proxy a -> HtsCSet c -> Bool
member _ = M.member (typeRep (Proxy :: Proxy a)) . unHS
notMember :: forall proxy c a. Typeable a => proxy a -> HtsCSet c -> Bool
notMember p = not . member p
insert :: forall c a. (Typeable a, c a) => a -> HtsCSet c -> HtsCSet c
insert a (HtsCSet hs) = HtsCSet (M.insert (typeRep (Proxy :: Proxy a)) (CastBox a) hs)
lookup :: forall c a. (Typeable a, c a) => HtsCSet c -> Maybe a
lookup (HtsCSet hs) = case M.lookup (typeRep (Proxy :: Proxy a)) hs of
(Just (CastBox a)) -> cast a
_ -> Nothing
lookupWithDefault :: forall c a. (Typeable a, c a) => a -> HtsCSet c -> a
lookupWithDefault a hs = case lookup hs of
Nothing -> a
(Just a') -> a'
update :: forall c a. (Typeable a, c a) => (a -> a) -> HtsCSet c -> HtsCSet c
update f = HtsCSet . M.adjust (mapCastBox f) (typeRep (Proxy :: Proxy a)) . unHS
existTypeOf :: forall c a. (Typeable a, c a) => a -> HtsCSet c -> Bool
existTypeOf _ (HtsCSet hs) = case M.lookup (typeRep (Proxy :: Proxy a)) hs of
(Just _) -> True
_ -> False
existTypeOfP :: forall proxy c a. (Typeable a, c a) => proxy a -> HtsCSet c -> Bool
existTypeOfP _ (HtsCSet hs) = case M.lookup (typeRep (Proxy :: Proxy a)) hs of
(Just _) -> True
_ -> False
data a :+ b = a :+ b
infixr 5 :+
class Append c a where
append :: a -> HtsCSet c -> HtsCSet c
fill :: (Append c a) => a -> HtsCSet c
fill = flip append empty
instance (Typeable a, c a, Append c b) => Append c (a :+ b) where
append (a :+ b) = insert a . (append b)
instance Append c () where
append _ hs = hs