HORIZON HASKELLDocslts/ghc-9.10.x248f8f02026-10-05Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05

Moduleghc-9.10.3GHC2021

GHC.Core.Coercion

Module for (a) type kinds and (b) type coercions, as used in System FC. See Expr for more on System FC and how coercions fit into it.

  • 21 types
  • 179 values
  • Packageghc-9.10.3
  • Exports200
  • LanguageGHC2021
  • LicenceBSD-3-Clause
  • SourceCoercion.hs

Main data type

19 declarations
datadata UnivCoProvenance
#

For simplicity, we have just one UnivCo that represents a coercion from some type to some other type, with (in general) no restrictions on the type. The UnivCoProvenance specifies more exactly what the coercion really is and why a program should (or shouldn't!) trust the coercion. It is reasonable to consider each constructor of UnivCoProvenance as a totally independent coercion form; their only commonality is that they don't tell you what types they coercion between. (That info is in the UnivCo constructor of Coercion.

Instances2Data, Outputable
datadata Var
#

Variable

Essentially a typed Name, that may also contain some additional information about the Var and its use sites.

Instances15Data, Ord, NamedThing, Outputable, Uniquable, HasOccName, …
typetype CoVar = Id
#

Coercion Variable

typetype TyCoVar = Id
#

Type or Coercion Variable

datadata Role
#

See Note [Roles] in GHC.Core.Coercion

Order of constructors matters: the Ord instance coincides with the *super*typing relation on roles.

Instances7Eq, Data, Ord, Outputable, Binary, Anno, …
  • Eq RoleDefined in ghc-9.10.3 · Language.Haskell.Syntax.Basic
  • Data RoleDefined in ghc-9.10.3 · Language.Haskell.Syntax.Basic
  • Ord RoleDefined in ghc-9.10.3 · Language.Haskell.Syntax.Basic
  • Outputable RoleDefined in ghc-9.10.3 · GHC.Core.Coercion.Axiom · orphan
  • Binary RoleDefined in ghc-9.10.3 · GHC.Core.Coercion.Axiom · orphan
  • type Anno (Maybe Role) = EpAnnCODefined in ghc-9.10.3 · GHC.Hs.Decls · orphan
  • type Anno (Maybe Role) = EpAnnCODefined in ghc-9.10.3 · GHC.Hs.Decls · orphan

Functions over coercions

If it is the case that

c :: (t1 ~ t2)

i.e. the kind of c relates t1 and t2, then coercionKind c = Pair t1 t2.

Constructing coercions

valuemkSymCo :: Coercion -> Coercion
#

Create a symmetric version of the given Coercion that asserts equality between the same types but in the other "direction", so a kind of t1 ~ t2 becomes the kind t2 ~ t1.

valuegetNthFun
  1. :: FunSel
  2. -> a

    multiplicity

  3. -> a

    argument

  4. -> a

    result

  5. -> a

    One of the above three

#

Extract the nth field of a FunCo

valuemkAppCo
  1. :: Coercion

    :: t1 ~r t2

  2. -> Coercion

    :: s1 ~N s2, where s1 :: k1, s2 :: k2

  3. -> Coercion

    :: t1 s1 ~r t2 s2

#

Apply a Coercion to another Coercion. The second coercion must be Nominal, unless the first is Phantom. If the first is Phantom, then the second can be either Phantom or Nominal.

Build a function Coercion from two other Coercions. That is, given co1 :: a ~ b and co2 :: x ~ y produce co :: (a -> x) ~ (b -> y) or (a => x) ~ (b => y), depending on the kind of a/b. This (most common) version takes a single FunTyFlag, which is used for both fco_afl and ftf_afr of the FunCo

valuemkPhantomCo :: Coercion -> Type -> Type -> Coercion
#

Make a phantom coercion between two types. The coercion passed in must be a nominal coercion between the kinds of the types.

Creates a new coercion with both of its types casted by different casts castCoercionKind g h1 h2, where g :: t1 ~r t2, has type (t1 |> h1) ~r (t2 |> h2). h1 and h2 must be nominal. It calls coercionKindRole, so it's quite inefficient (which I stands for) Use castCoercionKind2 instead if t1, t2, and r are known beforehand.

castCoercionKind1 g r t1 t2 h = coercionKind g r t1 t2 h h That is, it's a specialised form of castCoercionKind, where the two kind coercions are identical castCoercionKind1 g r t1 t2 h, where g :: t1 ~r t2, has type (t1 |> h) ~r (t2 |> h). h must be nominal. See Note [castCoercionKind1]

valuemkPrimEqPred :: Type -> Type -> Type
#

Creates a primitive nominal type equality predicate. t1 ~# t2 Invariant: the types are not Coercions

valuemkReprPrimEqPred :: Type -> Type -> Type
#

Creates a primitive representational type equality predicate. t1 ~R# t2 Invariant: the types are not Coercions

valuemkNomPrimEqPred :: Kind -> Type -> Type -> Type
#

Creates a primitive nominal type equality predicate with an explicit (but homogeneous) kind: (~#) k k ty1 ty2

Decomposition

datadata NormaliseStepResult ev
#

The result of stepping in a normalisation function. See topNormaliseTypeX.

Constructors

  • NS_Done

    Nothing more to do

  • NS_Abort

    Utter failure. The outer function should fail too.

  • NS_Step RecTcChecker Type ev

    We stepped, yielding new bits; ^ ev is evidence; Usually a co :: old type ~ new type

Instances2Functor, Outputable

Sometimes we want to look through a newtype and get its associated coercion. This function strips off newtype layers enough to reveal something that isn't a newtype. Specifically, here's the invariant:

topNormaliseNewType_maybe rec_nts ty = Just (co, ty')

then (a) co : ty ~R ty'. (b) ty' is not a newtype.

The function returns Nothing for non-newtypes, or unsaturated applications

This function does *not* look through type families, because it has no access to the type family environment. If you do have that at hand, consider to use topNormaliseType_maybe, which should be a drop-in replacement for topNormaliseNewType_maybe If topNormliseNewType_maybe ty = Just (co, ty'), then co : ty ~R ty'

valuetopNormaliseTypeX
  1. :: NormaliseStepper ev
  2. -> ev -> ev -> ev
  3. -> Type
  4. -> Maybe (ev, Type)
#

A general function for normalising the top-level of a type. It continues to use the provided NormaliseStepper until that function fails, and then this function returns. The roles of the coercions produced by the NormaliseStepper must all be the same, which is the role returned from the call to topNormaliseTypeX.

Typically ev is Coercion.

If topNormaliseTypeX step plus ty = Just (ev, ty') then ty ~ev1~ t1 ~ev2~ t2 ... ~evn~ ty' and ev = ev1 plus ev2 plus ... plus evn If it returns Nothing then no newtype unwrapping could happen

Extract a covar, if possible. This check is dirty. Be ashamed of yourself. (It's dirty because it cares about the structure of a coercion, which is morally reprehensible.)

valueisGReflCo :: Coercion -> Bool
#

Tests if this coercion is obviously a generalized reflexive coercion. Guaranteed to work very quickly.

valueisReflCo :: Coercion -> Bool
#

Tests if this coercion is obviously reflexive. Guaranteed to work very quickly. Sometimes a coercion can be reflexive, but not obviously so. c.f. isReflexiveCo

valueisReflexiveCo :: Coercion -> Bool
#

Slowly checks if the coercion is reflexive. Don't call this in a loop, as it walks over the entire coercion.

valueisGReflMCo :: MCoercion -> Bool
#

Tests if this MCoercion is obviously generalized reflexive Guaranteed to work very quickly.

Coercion variables

Free variables

Substitution

Lifting

liftCoSubst role lc ty produces a coercion (at role role) that coerces between lc_left(ty) and lc_right(ty), where lc_left is a substitution mapping type variables to the left-hand types of the mapped coercions in lc, and similar for lc_right.

Comparison

Forcing evaluation of coercions

Pretty-printing

8 declarations

Tidying

2 declarations

Other

8 declarations
valuebuildCoercion :: Type -> Type -> CoercionN
#

Assuming that two types are the same, ignoring coercions, find a nominal coercion between the types. This is useful when optimizing transitivity over coercion applications, where splitting two AppCos might yield different kinds. See Note [EtaAppCo] in GHC.Core.Coercion.Opt.

Given a coercion `co :: (t1 :: TYPE r1) ~ (t2 :: TYPE r2)` produce a coercion `rep_co :: r1 ~ r2` But actually it is possible that co :: (t1 :: CONSTRAINT r1) ~ (t2 :: CONSTRAINT r2) or co :: (t1 :: TYPE r1) ~ (t2 :: CONSTRAINT r2) or co :: (t1 :: CONSTRAINT r1) ~ (t2 :: TYPE r2) See Note [mkRuntimeRepCo]

valuehasCoercionHoleTy :: Type -> Bool
#

Is there a hetero-kind coercion hole in this type? (That is, a coercion hole with ch_hetero_kind=True.) See wrinkle (EIK2) of Note [Equalities with incompatible kinds] in GHC.Tc.Solver.Equality