on ff8e4de help sign in
48 lines 1.3 kB history raw
1{-# LANGUAGE KindSignatures #-}
2{-# LANGUAGE PolyKinds #-}
4module Data.TypeRep.CMap
5 ( TypeRepMap (..)
6 , empty
7 , insert
8 , keys
9 , lookup
10 , size
11 ) where
13import Prelude hiding (lookup)
15import Data.Proxy (Proxy (..))
16import Data.Typeable (TypeRep, Typeable, typeRep)
17import GHC.Base (Any)
18import Unsafe.Coerce (unsafeCoerce)
20import qualified Data.Map.Lazy as LMap
22-- | Map-like data structure with types served as the keys.
23newtype TypeRepMap (f :: k -> *) = TypeRepMap
24 { unMap :: LMap.Map TypeRep Any
25 }
27-- | Empty structure.
28empty :: TypeRepMap f
29empty = TypeRepMap mempty
31-- | Inserts the value with its type as a key.
32insert :: forall a f . Typeable a => f a -> TypeRepMap f -> TypeRepMap f
33insert val = TypeRepMap . LMap.insert (typeRep (Proxy :: Proxy a)) (unsafeCoerce val) . unMap
35-- | Looks up the value at the type.
36-- >>> let x = lookup $ insert (11 :: Int) empty
37-- >>> x :: Maybe Int
38-- Just 11
39-- >>> x :: Maybe ()
40-- Nothing
41lookup :: forall a f . Typeable a => TypeRepMap f -> Maybe (f a)
42lookup = fmap unsafeCoerce . LMap.lookup (typeRep (Proxy :: Proxy a)) . unMap
44size :: TypeRepMap f -> Int
45size = LMap.size . unMap
47keys :: TypeRepMap f -> [TypeRep]
48keys = LMap.keys . unMap