{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE Trustworthy #-} {-# LANGUAGE TypeInType #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE CPP #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE TypeApplications #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Typeable.Internal -- Copyright : (c) The University of Glasgow, CWI 2001--2011 -- License : BSD-style (see the file libraries/base/LICENSE) -- -- The representations of the types TyCon and TypeRep, and the -- function mkTyCon which is used by derived instances of Typeable to -- construct a TyCon. -- ----------------------------------------------------------------------------- module Data.Typeable.Internal ( -- * Typeable and kind polymorphism -- -- #kind_instantiation -- * Miscellaneous Fingerprint(..), -- * Typeable class Typeable(..), withTypeable, -- * Module Module, -- Abstract moduleName, modulePackage, rnfModule, -- * TyCon TyCon, -- Abstract tyConPackage, tyConModule, tyConName, tyConKindArgs, tyConKindRep, tyConFingerprint, KindRep(.., KindRepTypeLit), TypeLitSort(..), rnfTyCon, -- * TypeRep TypeRep, pattern App, pattern Con, pattern Con', pattern Fun, typeRep, typeOf, typeRepTyCon, typeRepFingerprint, rnfTypeRep, eqTypeRep, typeRepKind, splitApps, -- * SomeTypeRep SomeTypeRep(..), someTypeRep, someTypeRepTyCon, someTypeRepFingerprint, rnfSomeTypeRep, -- * Construction -- | These are for internal use only mkTrCon, mkTrApp, mkTrFun, mkTyCon, mkTyCon#, typeSymbolTypeRep, typeNatTypeRep, ) where import GHC.Base import qualified GHC.Arr as A import GHC.Types ( TYPE ) import Data.Type.Equality import GHC.List ( splitAt, foldl' ) import GHC.Word import GHC.Show import GHC.TypeLits ( KnownSymbol, symbolVal' ) import GHC.TypeNats ( KnownNat, natVal' ) import Unsafe.Coerce ( unsafeCoerce ) import GHC.Fingerprint.Type import {-# SOURCE #-} GHC.Fingerprint -- loop: GHC.Fingerprint -> Foreign.Ptr -> Data.Typeable -- Better to break the loop here, because we want non-SOURCE imports -- of Data.Typeable as much as possible so we can optimise the derived -- instances. #include "MachDeps.h" {- ********************************************************************* * * The TyCon type * * ********************************************************************* -} modulePackage :: Module -> String modulePackage (Module p _) = trNameString p moduleName :: Module -> String moduleName (Module _ m) = trNameString m tyConPackage :: TyCon -> String tyConPackage (TyCon _ _ m _ _ _) = modulePackage m tyConModule :: TyCon -> String tyConModule (TyCon _ _ m _ _ _) = moduleName m tyConName :: TyCon -> String tyConName (TyCon _ _ _ n _ _) = trNameString n trNameString :: TrName -> String trNameString (TrNameS s) = unpackCStringUtf8# s trNameString (TrNameD s) = s tyConFingerprint :: TyCon -> Fingerprint tyConFingerprint (TyCon hi lo _ _ _ _) = Fingerprint (W64# hi) (W64# lo) tyConKindArgs :: TyCon -> Int tyConKindArgs (TyCon _ _ _ _ n _) = I# n tyConKindRep :: TyCon -> KindRep tyConKindRep (TyCon _ _ _ _ _ k) = k -- | Helper to fully evaluate 'TyCon' for use as @NFData(rnf)@ implementation -- -- @since 4.8.0.0 rnfModule :: Module -> () rnfModule (Module p m) = rnfTrName p `seq` rnfTrName m rnfTrName :: TrName -> () rnfTrName (TrNameS _) = () rnfTrName (TrNameD n) = rnfString n rnfKindRep :: KindRep -> () rnfKindRep (KindRepTyConApp tc args) = rnfTyCon tc `seq` rnfList rnfKindRep args rnfKindRep (KindRepVar _) = () rnfKindRep (KindRepApp a b) = rnfKindRep a `seq` rnfKindRep b rnfKindRep (KindRepFun a b) = rnfKindRep a `seq` rnfKindRep b rnfKindRep (KindRepTYPE rr) = rnfRuntimeRep rr rnfKindRep (KindRepTypeLitS _ _) = () rnfKindRep (KindRepTypeLitD _ t) = rnfString t rnfRuntimeRep :: RuntimeRep -> () rnfRuntimeRep (VecRep !_ !_) = () rnfRuntimeRep !_ = () rnfList :: (a -> ()) -> [a] -> () rnfList _ [] = () rnfList force (x:xs) = force x `seq` rnfList force xs rnfString :: [Char] -> () rnfString = rnfList (`seq` ()) rnfTyCon :: TyCon -> () rnfTyCon (TyCon _ _ m n _ k) = rnfModule m `seq` rnfTrName n `seq` rnfKindRep k {- ********************************************************************* * * The TypeRep type * * ********************************************************************* -} -- | A concrete representation of a (monomorphic) type. -- 'TypeRep' supports reasonably efficient equality. data TypeRep (a :: k) where TrTyCon :: {-# UNPACK #-} !Fingerprint -> !TyCon -> [SomeTypeRep] -> TypeRep (a :: k) TrApp :: forall k1 k2 (a :: k1 -> k2) (b :: k1). {-# UNPACK #-} !Fingerprint -> TypeRep (a :: k1 -> k2) -> TypeRep (b :: k1) -> TypeRep (a b) TrFun :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep) (a :: TYPE r1) (b :: TYPE r2). {-# UNPACK #-} !Fingerprint -> TypeRep a -> TypeRep b -> TypeRep (a -> b) -- Compare keys for equality -- | @since 2.01 instance Eq (TypeRep a) where _ == _ = True {-# INLINABLE (==) #-} instance TestEquality TypeRep where a `testEquality` b | Just HRefl <- eqTypeRep a b = Just Refl | otherwise = Nothing {-# INLINEABLE testEquality #-} -- | @since 4.4.0.0 instance Ord (TypeRep a) where compare _ _ = EQ {-# INLINABLE compare #-} -- | A non-indexed type representation. data SomeTypeRep where SomeTypeRep :: forall k (a :: k). !(TypeRep a) -> SomeTypeRep instance Eq SomeTypeRep where SomeTypeRep a == SomeTypeRep b = case a `eqTypeRep` b of Just _ -> True Nothing -> False instance Ord SomeTypeRep where SomeTypeRep a `compare` SomeTypeRep b = typeRepFingerprint a `compare` typeRepFingerprint b -- | The function type constructor. -- -- For instance, -- @ -- typeRep \@(Int -> Char) === Fun (typeRep \@Int) (typeRep \@Char) -- @ -- pattern Fun :: forall k (fun :: k). () => forall (r1 :: RuntimeRep) (r2 :: RuntimeRep) (arg :: TYPE r1) (res :: TYPE r2). (k ~ Type, fun ~~ (arg -> res)) => TypeRep arg -> TypeRep res -> TypeRep fun pattern Fun arg res <- TrFun _ arg res where Fun arg res = mkTrFun arg res -- | Observe the 'Fingerprint' of a type representation -- -- @since 4.8.0.0 typeRepFingerprint :: TypeRep a -> Fingerprint typeRepFingerprint (TrTyCon fpr _ _) = fpr typeRepFingerprint (TrApp fpr _ _) = fpr typeRepFingerprint (TrFun fpr _ _) = fpr -- | Construct a representation for a type constructor -- applied at a monomorphic kind. -- -- Note that this is unsafe as it allows you to construct -- ill-kinded types. mkTrCon :: forall k (a :: k). TyCon -> [SomeTypeRep] -> TypeRep a mkTrCon tc kind_vars = TrTyCon fpr tc kind_vars where fpr_tc = tyConFingerprint tc fpr_kvs = map someTypeRepFingerprint kind_vars fpr = fingerprintFingerprints (fpr_tc:fpr_kvs) -- | Construct a representation for a type application. -- -- Note that this is known-key to the compiler, which uses it in desugar -- 'Typeable' evidence. mkTrApp :: forall k1 k2 (a :: k1 -> k2) (b :: k1). TypeRep (a :: k1 -> k2) -> TypeRep (b :: k1) -> TypeRep (a b) mkTrApp a b = TrApp fpr a b where fpr_a = typeRepFingerprint a fpr_b = typeRepFingerprint b fpr = fingerprintFingerprints [fpr_a, fpr_b] -- | A type application. -- -- For instance, -- @ -- typeRep \@(Maybe Int) === App (typeRep \@Maybe) (typeRep \@Int) -- @ -- Note that this will never match a function type (e.g. @Int -> Char@). -- pattern App :: forall k2 (t :: k2). () => forall k1 (a :: k1 -> k2) (b :: k1). (t ~ a b) => TypeRep a -> TypeRep b -> TypeRep t pattern App f x <- TrApp _ f x where App f x = mkTrApp f x -- | Use a 'TypeRep' as 'Typeable' evidence. withTypeable :: forall a r. TypeRep a -> (Typeable a => r) -> r withTypeable rep k = unsafeCoerce k' rep where k' :: Gift a r k' = Gift k -- | A helper to satisfy the type checker in 'withTypeable'. newtype Gift a r = Gift (Typeable a => r) -- | Pattern match on a type constructor pattern Con :: forall k (a :: k). TyCon -> TypeRep a pattern Con con <- TrTyCon _ con _ -- | Pattern match on a type constructor including its instantiated kind -- variables. -- -- For instance, -- @ -- App (Con' proxyTyCon ks) intRep = typeRep @(Proxy \@Int) -- @ -- will bring into scope, -- @ -- proxyTyCon :: TyCon -- ks == [someTypeRep @Type] :: [SomeTypeRep] -- intRep == typeRep @Int -- @ -- pattern Con' :: forall k (a :: k). TyCon -> [SomeTypeRep] -> TypeRep a pattern Con' con ks <- TrTyCon _ con ks {-# COMPLETE Fun, App, Con #-} {-# COMPLETE Fun, App, Con' #-} ----------------- Observation --------------------- -- | Observe the type constructor of a quantified type representation. someTypeRepTyCon :: SomeTypeRep -> TyCon someTypeRepTyCon (SomeTypeRep t) = typeRepTyCon t -- | Observe the type constructor of a type representation typeRepTyCon :: TypeRep a -> TyCon typeRepTyCon (TrTyCon _ tc _) = tc typeRepTyCon (TrApp _ a _) = typeRepTyCon a typeRepTyCon (TrFun _ _ _) = typeRepTyCon $ typeRep @(->) -- | Type equality -- -- @since 4.10 eqTypeRep :: forall k1 k2 (a :: k1) (b :: k2). TypeRep a -> TypeRep b -> Maybe (a :~~: b) eqTypeRep a b | typeRepFingerprint a == typeRepFingerprint b = Just (unsafeCoerce HRefl) | otherwise = Nothing ------------------------------------------------------------- -- -- Computing kinds -- ------------------------------------------------------------- -- | Observe the kind of a type. typeRepKind :: TypeRep (a :: k) -> TypeRep k typeRepKind (TrTyCon _ tc args) = unsafeCoerceRep $ tyConKind tc args typeRepKind (TrApp _ f _) | Fun _ res <- typeRepKind f = res | otherwise = error ("Ill-kinded type application: " ++ show (typeRepKind f)) typeRepKind (TrFun _ _ _) = typeRep @Type tyConKind :: TyCon -> [SomeTypeRep] -> SomeTypeRep tyConKind (TyCon _ _ _ _ nKindVars# kindRep) kindVars = let kindVarsArr :: A.Array KindBndr SomeTypeRep kindVarsArr = A.listArray (0, I# (nKindVars# -# 1#)) kindVars in instantiateKindRep kindVarsArr kindRep instantiateKindRep :: A.Array KindBndr SomeTypeRep -> KindRep -> SomeTypeRep instantiateKindRep vars = go where go :: KindRep -> SomeTypeRep go (KindRepTyConApp tc args) = let n_kind_args = tyConKindArgs tc (kind_args, ty_args) = splitAt n_kind_args args -- First instantiate tycon kind arguments tycon_app = SomeTypeRep $ mkTrCon tc (map go kind_args) -- Then apply remaining type arguments applyTy :: SomeTypeRep -> KindRep -> SomeTypeRep applyTy (SomeTypeRep acc) ty | SomeTypeRep ty' <- go ty = SomeTypeRep $ mkTrApp (unsafeCoerce acc) (unsafeCoerce ty') in foldl' applyTy tycon_app ty_args go (KindRepVar var) = vars A.! var go (KindRepApp f a) = SomeTypeRep $ App (unsafeCoerceRep $ go f) (unsafeCoerceRep $ go a) go (KindRepFun a b) = SomeTypeRep $ Fun (unsafeCoerceRep $ go a) (unsafeCoerceRep $ go b) go (KindRepTYPE r) = unkindedTypeRep $ tYPE `kApp` runtimeRepTypeRep r go (KindRepTypeLitS sort s) = mkTypeLitFromString sort (unpackCStringUtf8# s) go (KindRepTypeLitD sort s) = mkTypeLitFromString sort s tYPE = kindedTypeRep @(RuntimeRep -> Type) @TYPE unsafeCoerceRep :: SomeTypeRep -> TypeRep a unsafeCoerceRep (SomeTypeRep r) = unsafeCoerce r unkindedTypeRep :: SomeKindedTypeRep k -> SomeTypeRep unkindedTypeRep (SomeKindedTypeRep x) = SomeTypeRep x data SomeKindedTypeRep k where SomeKindedTypeRep :: forall (a :: k). TypeRep a -> SomeKindedTypeRep k kApp :: SomeKindedTypeRep (k -> k') -> SomeKindedTypeRep k -> SomeKindedTypeRep k' kApp (SomeKindedTypeRep f) (SomeKindedTypeRep a) = SomeKindedTypeRep (App f a) kindedTypeRep :: forall (a :: k). Typeable a => SomeKindedTypeRep k kindedTypeRep = SomeKindedTypeRep (typeRep @a) buildList :: forall k. Typeable k => [SomeKindedTypeRep k] -> SomeKindedTypeRep [k] buildList = foldr cons nil where nil = kindedTypeRep @[k] @'[] cons x rest = SomeKindedTypeRep (typeRep @'(:)) `kApp` x `kApp` rest runtimeRepTypeRep :: RuntimeRep -> SomeKindedTypeRep RuntimeRep runtimeRepTypeRep r = case r of LiftedRep -> rep @'LiftedRep UnliftedRep -> rep @'UnliftedRep VecRep c e -> kindedTypeRep @_ @'VecRep `kApp` vecCountTypeRep c `kApp` vecElemTypeRep e TupleRep rs -> kindedTypeRep @_ @'TupleRep `kApp` buildList (map runtimeRepTypeRep rs) SumRep rs -> kindedTypeRep @_ @'SumRep `kApp` buildList (map runtimeRepTypeRep rs) IntRep -> rep @'IntRep WordRep -> rep @'WordRep Int64Rep -> rep @'Int64Rep Word64Rep -> rep @'Word64Rep AddrRep -> rep @'AddrRep FloatRep -> rep @'FloatRep DoubleRep -> rep @'DoubleRep where rep :: forall (a :: RuntimeRep). Typeable a => SomeKindedTypeRep RuntimeRep rep = kindedTypeRep @RuntimeRep @a vecCountTypeRep :: VecCount -> SomeKindedTypeRep VecCount vecCountTypeRep c = case c of Vec2 -> rep @'Vec2 Vec4 -> rep @'Vec4 Vec8 -> rep @'Vec8 Vec16 -> rep @'Vec16 Vec32 -> rep @'Vec32 Vec64 -> rep @'Vec64 where rep :: forall (a :: VecCount). Typeable a => SomeKindedTypeRep VecCount rep = kindedTypeRep @VecCount @a vecElemTypeRep :: VecElem -> SomeKindedTypeRep VecElem vecElemTypeRep e = case e of Int8ElemRep -> rep @'Int8ElemRep Int16ElemRep -> rep @'Int16ElemRep Int32ElemRep -> rep @'Int32ElemRep Int64ElemRep -> rep @'Int64ElemRep Word8ElemRep -> rep @'Word8ElemRep Word16ElemRep -> rep @'Word16ElemRep Word32ElemRep -> rep @'Word32ElemRep Word64ElemRep -> rep @'Word64ElemRep FloatElemRep -> rep @'FloatElemRep DoubleElemRep -> rep @'DoubleElemRep where rep :: forall (a :: VecElem). Typeable a => SomeKindedTypeRep VecElem rep = kindedTypeRep @VecElem @a ------------------------------------------------------------- -- -- The Typeable class and friends -- ------------------------------------------------------------- -- | The class 'Typeable' allows a concrete representation of a type to -- be calculated. class Typeable (a :: k) where typeRep# :: TypeRep a typeRep :: Typeable a => TypeRep a typeRep = typeRep# typeOf :: Typeable a => a -> TypeRep a typeOf _ = typeRep -- | Takes a value of type @a@ and returns a concrete representation -- of that type. -- -- @since 4.7.0.0 someTypeRep :: forall proxy a. Typeable a => proxy a -> SomeTypeRep someTypeRep _ = SomeTypeRep (typeRep :: TypeRep a) {-# INLINE typeRep #-} someTypeRepFingerprint :: SomeTypeRep -> Fingerprint someTypeRepFingerprint (SomeTypeRep t) = typeRepFingerprint t ----------------- Showing TypeReps -------------------- -- This follows roughly the precedence structure described in Note [Precedence -- in types]. instance Show (TypeRep (a :: k)) where showsPrec = showTypeable showTypeable :: Int -> TypeRep (a :: k) -> ShowS showTypeable _ rep | Just HRefl <- rep `eqTypeRep` (typeRep :: TypeRep Type) = showChar '*' | isListTyCon tc, [ty] <- tys = showChar '[' . shows ty . showChar ']' | isTupleTyCon tc = showChar '(' . showArgs (showChar ',') tys . showChar ')' where (tc, tys) = splitApps rep showTypeable p (TrTyCon _ tycon []) = showsPrec p tycon showTypeable p (TrTyCon _ tycon args) = showParen (p > 9) $ showsPrec p tycon . showChar ' ' . showArgs (showChar ' ') args showTypeable p (TrFun _ x r) = showParen (p > 8) $ showsPrec 9 x . showString " -> " . showsPrec 8 r showTypeable p (TrApp _ f x) = showParen (p > 9) $ showsPrec 8 f . showChar ' ' . showsPrec 10 x -- | @since 4.10.0.0 instance Show SomeTypeRep where showsPrec p (SomeTypeRep ty) = showsPrec p ty splitApps :: TypeRep a -> (TyCon, [SomeTypeRep]) splitApps = go [] where go :: [SomeTypeRep] -> TypeRep a -> (TyCon, [SomeTypeRep]) go xs (TrTyCon _ tc _) = (tc, xs) go xs (TrApp _ f x) = go (SomeTypeRep x : xs) f go [] (TrFun _ a b) = (funTyCon, [SomeTypeRep a, SomeTypeRep b]) go _ (TrFun _ _ _) = errorWithoutStackTrace "Data.Typeable.Internal.splitApps: Impossible" funTyCon :: TyCon funTyCon = typeRepTyCon (typeRep @(->)) isListTyCon :: TyCon -> Bool isListTyCon tc = tc == typeRepTyCon (typeRep :: TypeRep [Int]) isTupleTyCon :: TyCon -> Bool isTupleTyCon tc | ('(':',':_) <- tyConName tc = True | otherwise = False showArgs :: Show a => ShowS -> [a] -> ShowS showArgs _ [] = id showArgs _ [a] = showsPrec 10 a showArgs sep (a:as) = showsPrec 10 a . sep . showArgs sep as -- | Helper to fully evaluate 'TypeRep' for use as @NFData(rnf)@ implementation -- -- @since 4.8.0.0 rnfTypeRep :: TypeRep a -> () rnfTypeRep (TrTyCon _ tyc _) = rnfTyCon tyc rnfTypeRep (TrApp _ f x) = rnfTypeRep f `seq` rnfTypeRep x rnfTypeRep (TrFun _ x y) = rnfTypeRep x `seq` rnfTypeRep y -- | Helper to fully evaluate 'SomeTypeRep' for use as @NFData(rnf)@ -- implementation -- -- @since 4.10.0.0 rnfSomeTypeRep :: SomeTypeRep -> () rnfSomeTypeRep (SomeTypeRep r) = rnfTypeRep r {- ********************************************************* * * * TyCon/TypeRep definitions for type literals * * (Symbol and Nat) * * * ********************************************************* -} pattern KindRepTypeLit :: TypeLitSort -> String -> KindRep pattern KindRepTypeLit sort t <- (getKindRepTypeLit -> Just (sort, t)) where KindRepTypeLit sort t = KindRepTypeLitD sort t {-# COMPLETE KindRepTyConApp, KindRepVar, KindRepApp, KindRepFun, KindRepTYPE, KindRepTypeLit #-} getKindRepTypeLit :: KindRep -> Maybe (TypeLitSort, String) getKindRepTypeLit (KindRepTypeLitS sort t) = Just (sort, unpackCStringUtf8# t) getKindRepTypeLit (KindRepTypeLitD sort t) = Just (sort, t) getKindRepTypeLit _ = Nothing -- | Exquisitely unsafe. mkTyCon# :: Addr# -- ^ package name -> Addr# -- ^ module name -> Addr# -- ^ the name of the type constructor -> Int# -- ^ number of kind variables -> KindRep -- ^ kind representation -> TyCon -- ^ A unique 'TyCon' object mkTyCon# pkg modl name n_kinds kind_rep | Fingerprint (W64# hi) (W64# lo) <- fingerprint = TyCon hi lo mod (TrNameS name) n_kinds kind_rep where mod = Module (TrNameS pkg) (TrNameS modl) fingerprint :: Fingerprint fingerprint = mkTyConFingerprint (unpackCStringUtf8# pkg) (unpackCStringUtf8# modl) (unpackCStringUtf8# name) -- it is extremely important that this fingerprint computation -- remains in sync with that in TcTypeable to ensure that type -- equality is correct. -- | Exquisitely unsafe. mkTyCon :: String -- ^ package name -> String -- ^ module name -> String -- ^ the name of the type constructor -> Int -- ^ number of kind variables -> KindRep -- ^ kind representation -> TyCon -- ^ A unique 'TyCon' object -- Used when the strings are dynamically allocated, -- eg from binary deserialisation mkTyCon pkg modl name (I# n_kinds) kind_rep | Fingerprint (W64# hi) (W64# lo) <- fingerprint = TyCon hi lo mod (TrNameD name) n_kinds kind_rep where mod = Module (TrNameD pkg) (TrNameD modl) fingerprint :: Fingerprint fingerprint = mkTyConFingerprint pkg modl name -- This must match the computation done in TcTypeable.mkTyConRepTyConRHS. mkTyConFingerprint :: String -- ^ package name -> String -- ^ module name -> String -- ^ tycon name -> Fingerprint mkTyConFingerprint pkg_name mod_name tycon_name = fingerprintFingerprints [ fingerprintString pkg_name , fingerprintString mod_name , fingerprintString tycon_name ] mkTypeLitTyCon :: String -> TyCon -> TyCon mkTypeLitTyCon name kind_tycon = mkTyCon "base" "GHC.TypeLits" name 0 kind where kind = KindRepTyConApp kind_tycon [] -- | Used to make `'Typeable' instance for things of kind Nat typeNatTypeRep :: KnownNat a => Proxy# a -> TypeRep a typeNatTypeRep p = typeLitTypeRep (show (natVal' p)) tcNat -- | Used to make `'Typeable' instance for things of kind Symbol typeSymbolTypeRep :: KnownSymbol a => Proxy# a -> TypeRep a typeSymbolTypeRep p = typeLitTypeRep (show (symbolVal' p)) tcSymbol mkTypeLitFromString :: TypeLitSort -> String -> SomeTypeRep mkTypeLitFromString TypeLitSymbol s = SomeTypeRep $ (typeLitTypeRep s tcSymbol :: TypeRep Symbol) mkTypeLitFromString TypeLitNat s = SomeTypeRep $ (typeLitTypeRep s tcSymbol :: TypeRep Nat) tcSymbol :: TyCon tcSymbol = typeRepTyCon (typeRep @Symbol) tcNat :: TyCon tcNat = typeRepTyCon (typeRep @Nat) -- | An internal function, to make representations for type literals. typeLitTypeRep :: forall (a :: k). (Typeable k) => String -> TyCon -> TypeRep a typeLitTypeRep nm kind_tycon = mkTrCon (mkTypeLitTyCon nm kind_tycon) [] -- | For compiler use. mkTrFun :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep) (a :: TYPE r1) (b :: TYPE r2). TypeRep a -> TypeRep b -> TypeRep ((a -> b) :: Type) mkTrFun arg res = TrFun fpr arg res where fpr = fingerprintFingerprints [ typeRepFingerprint arg , typeRepFingerprint res] {- $kind_instantiation Consider a type like 'Data.Proxy.Proxy', @ data Proxy :: forall k. k -> Type @ One might think that one could decompose an instantiation of this type like @Proxy Int@ into two applications, @ 'App' (App a b) c === typeRep @(Proxy Int) @ where, @ a = typeRep @Proxy b = typeRep @Type c = typeRep @Int @ However, this isn't the case. Instead we can only decompose into an application and a constructor, @ 'App' ('Con' proxyTyCon) (typeRep @Int) === typeRep @(Proxy Int) @ The reason for this is that 'Typeable' can only represent /kind-monomorphic/ types. That is, we must saturate enough of @Proxy@\'s arguments to fully determine its kind. In the particular case of @Proxy@ this means we must instantiate the kind variable @k@ such that no @forall@-quantified variables remain. While it is not possible to decompose the 'Con' above into an application, it is possible to observe the kind variable instantiations of the constructor with the 'Con\'' pattern, @ 'App' (Con' proxyTyCon kinds) _ === typeRep @(Proxy Int) @ Here @kinds@ will be @[typeRep \@Type]@. -}