module Data.TypeMap.Internal.Unsafe
( module Data.TypeMap.Internal.Unsafe
, module Unsafe
) where
import Data.Coerce
import Data.Proxy as Unsafe (Proxy(..))
import GHC.Prim as Unsafe (Any)
import GHC.TypeLits as Unsafe (KnownNat)
import GHC.TypeLits (type (+), natVal)
import Unsafe.Coerce as Unsafe
type family Index (a :: k) (d :: [(k, *)]) where
Index a ('(a, _) ': _) = 0
Index a (_ ': d) = 1 + Index a d
type family Lookup (a :: k) (d :: [(k, *)]) where
Lookup a ('(a, b) ': _) = b
Lookup a (_ ': d) = Lookup a d
type family Snoc (d :: [k]) (a :: k) where
Snoc '[] a = '[a]
Snoc (x ': d) a = x ': Snoc d a
type family Last (d :: [k]) where
Last (x ': '[]) = x
Last (_ ': d) = Last d
type family Init (d :: [k]) where
Init (_ ': '[]) = '[]
Init (x ': d) = x ': Init d
unsafeIndex
:: forall a d f m
. (KnownNat (Index a d), Coercible (f Any) (m d))
=> (forall c. f c -> Int -> c)
-> m d -> Lookup a d
unsafeIndex index = unsafeCoerce (flip index na)
where
na = fromInteger (natVal (Proxy @(Index a d))) :: Int
unsafeCons
:: forall a d b f m
. (Coercible (f Any) (m d), Coercible (f Any) (m ('(a, b) ': d)))
=> (forall c. c -> f c -> f c)
-> b -> m d -> m ('(a, b) ': d)
unsafeCons = unsafeCoerce
unsafeSnoc
:: forall a d b f m
. (Last d ~ '(a, b), Coercible (f Any) (m (Init d)), Coercible (f Any) (m d))
=> (forall c. f c -> c -> f c)
-> m (Init d) -> b -> m d
unsafeSnoc = unsafeCoerce