on 54feff4 help sign in
44 lines 1.1 kB history raw
1{-# LANGUAGE ExplicitForAll #-}
2{-# LANGUAGE ScopedTypeVariables #-}
4module Data.TypeRep.Map
5 ( TypeRepMap (..)
6 , empty
7 , insert
8 , lookup
9 , size
10 ) where
12import Prelude hiding (lookup)
14import Data.Proxy (Proxy (..))
15import Data.Typeable (TypeRep, Typeable, typeOf, typeRep)
16import GHC.Base (Any)
17import Unsafe.Coerce (unsafeCoerce)
19import qualified Data.Map.Lazy as LMap
21-- | Map-like data structure with types served as the keys.
22newtype TypeRepMap = TypeRepMap
23 { unMap :: LMap.Map TypeRep Any
24 }
26-- | Empty structure.
27empty :: TypeRepMap
28empty = TypeRepMap mempty
30-- | Inserts the value with its type as a key.
31insert :: Typeable a => a -> TypeRepMap -> TypeRepMap
32insert val = TypeRepMap . LMap.insert (typeOf val) (unsafeCoerce val) . unMap
34-- | Looks up the value at the type.
35-- >>> let x = lookup $ insert (11 :: Int) empty
36-- >>> x :: Maybe Int
37-- Just 11
38-- >>> x :: Maybe ()
39-- Nothing
40lookup :: forall a . Typeable a => TypeRepMap -> Maybe a
41lookup = fmap unsafeCoerce . LMap.lookup (typeRep (Proxy :: Proxy a)) . unMap
43size :: TypeRepMap -> Int
44size = LMap.size . unMap