module Data.Singletons.TypeRepStar (
Sing(STypeRep)
) where
import Data.Singletons.Prelude.Instances
import Data.Singletons
import Data.Singletons.Types
import Data.Singletons.Prelude.Eq
import Data.Typeable
import Unsafe.Coerce
import Data.Singletons.Decide
#if __GLASGOW_HASKELL__ >= 707
import GHC.Exts ( Proxy# )
import Data.Type.Coercion
import Data.Type.Equality
#else
eqT :: (Typeable a, Typeable b) => Maybe (a :~: b)
eqT = gcast Refl
#endif
data instance Sing (a :: *) where
STypeRep :: Typeable a => Sing a
instance Typeable a => SingI (a :: *) where
sing = STypeRep
instance SingKind ('KProxy :: KProxy *) where
type DemoteRep ('KProxy :: KProxy *) = TypeRep
fromSing (STypeRep :: Sing a) = typeOf (undefined :: a)
toSing = dirty_mk_STypeRep
instance PEq ('KProxy :: KProxy *) where
#if __GLASGOW_HASKELL__ < 707
type (a :: *) :== (a :: *) = True
#else
type (a :: *) :== (b :: *) = a == b
#endif
instance SEq ('KProxy :: KProxy *) where
(STypeRep :: Sing a) %:== (STypeRep :: Sing b) =
case (eqT :: Maybe (a :~: b)) of
Just Refl -> STrue
Nothing -> unsafeCoerce SFalse
instance SDecide ('KProxy :: KProxy *) where
(STypeRep :: Sing a) %~ (STypeRep :: Sing b) =
case (eqT :: Maybe (a :~: b)) of
Just Refl -> Proved Refl
Nothing -> Disproved (\Refl -> error "Data.Typeable.eqT failed")
#if __GLASGOW_HASKELL__ >= 707
instance TestCoercion Sing where
testCoercion (STypeRep :: Sing a) (STypeRep :: Sing b) =
case (eqT :: Maybe (a :~: b)) of
Just Refl -> Just Coercion
Nothing -> Nothing
#endif
newtype DI = Don'tInstantiate (Typeable a => Sing a)
dirty_mk_STypeRep :: TypeRep -> SomeSing ('KProxy :: KProxy *)
dirty_mk_STypeRep rep =
#if __GLASGOW_HASKELL__ >= 707
let justLikeTypeable :: Proxy# a -> TypeRep
justLikeTypeable _ = rep
in
#else
let justLikeTypeable :: a -> TypeRep
justLikeTypeable _ = rep
in
#endif
unsafeCoerce (Don'tInstantiate STypeRep) justLikeTypeable