module Data.TypeMap.Internal.Dynamic.Alt where
#if !MIN_VERSION_base(4,8,0)
import Control.Applicative (Applicative, (<$>))
#endif
import Data.Typeable
#if MIN_VERSION_base(4,10,0)
import GHC.Exts (Any)
import qualified Type.Reflection as T
#else
import GHC.Prim (Any, Proxy#)
#endif
import Unsafe.Coerce
import qualified Data.Map as Map
import Data.TypeMap.Internal.Dynamic
(TypeMap(..), Item, Typed, UnTyped, ItemFun, ItemKleisli)
insert
:: forall t x proxy
. Typeable t => Item x t -> TypeMap x -> TypeMap x
insert v (TypeMap m) = TypeMap (Map.insert (typeRep (Proxy @t)) (coerce v) m)
where
coerce :: Item x t -> Any
coerce = unsafeCoerce
lookup
:: forall t x proxy
. Typeable t => TypeMap x -> Maybe (Item x t)
lookup (TypeMap m) = coerce (Map.lookup (typeRep (Proxy @t)) m)
where
coerce :: Maybe Any -> Maybe (Item x t)
coerce = unsafeCoerce
map
:: forall x y. (forall t. Typeable t => Item x t -> Item y t)
-> TypeMap x -> TypeMap y
map f (TypeMap m) = TypeMap (Map.mapWithKey f' m)
where
f' = withTypeRep @(ItemFun x y)
(Typed_ (f @t) :: forall t. Typeable t => Typed_ (ItemFun x y) t)
traverse
:: forall f x y
. Applicative f
=> (forall t. Typeable t => Item x t -> f (Item y t))
-> TypeMap x -> f (TypeMap y)
traverse f (TypeMap m) = TypeMap <$> Map.traverseWithKey f' m
where
f' = withTypeRep @(ItemKleisli f x y)
(Typed_ (f @t) :: forall t. Typeable t => Typed_ (ItemKleisli f x y) t)
newtype Typed_ x t = Typed_ (Typed x t)
withTypeRep
:: forall x
. (forall t. Typeable t => Typed_ x t)
-> TypeRep -> UnTyped x
#if MIN_VERSION_base(4,10,0)
withTypeRep f rep =
case rep of
T.SomeTypeRep (rep :: T.TypeRep t) ->
(unsafeCoerce
((\rep -> T.withTypeable rep f) :: forall a. T.TypeRep a -> Typed_ x a)
:: T.TypeRep t -> UnTyped x) rep
#else
withTypeRep f rep =
withTypeable (WithTypeable f :: WithTypeable x) (\_ -> rep)
newtype WithTypeable x
= WithTypeable (forall t. Typeable t => Typed_ x t)
withTypeable
:: WithTypeable x -> (Proxy# () -> TypeRep) -> UnTyped x
withTypeable = unsafeCoerce
#endif