{-# LANGUAGE PolyKinds #-}
module Data.TypeRep.CMap
( TypeRepMap (..)
, empty
, insert
, keys
, lookup
, size
) where
import Prelude hiding (lookup)
import Control.DeepSeq
import Data.Kind (Type)
import Data.Proxy (Proxy (..))
import Data.Typeable (TypeRep, Typeable, typeRep)
import GHC.Base (Any)
import Unsafe.Coerce (unsafeCoerce)
import qualified Data.Map.Lazy as LMap
newtype TypeRepMap (f :: k -> Type) = TypeRepMap
{ unMap :: LMap.Map TypeRep Any
}
instance NFData (TypeRepMap f) where
rnf x = rnf (keys x) `seq` ()
empty :: TypeRepMap f
empty = TypeRepMap mempty
insert :: forall a f . Typeable a => f a -> TypeRepMap f -> TypeRepMap f
insert val = TypeRepMap . LMap.insert (typeRep (Proxy :: Proxy a)) (unsafeCoerce val) . unMap
lookup :: forall a f . Typeable a => TypeRepMap f -> Maybe (f a)
lookup = fmap unsafeCoerce . LMap.lookup (typeRep (Proxy :: Proxy a)) . unMap
size :: TypeRepMap f -> Int
size = LMap.size . unMap
keys :: TypeRepMap f -> [TypeRep]
keys = LMap.keys . unMap