HORIZON HASKELLDocslts/ghc-10.0.x2b276322026-10-31Search packagesCtrl K
Theme: |

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 2b27632 · 2026-10-31

Moduleghc-lib-parser-9.14.1.20251220GHC2021

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.

Contents
  1. Main data type
  2. Functions over coercions
  3. Constructing coercions
  4. Decomposition
  5. Coercion variables
  6. Free variables
  7. Substitution
  8. Lifting
  9. Comparison
  10. Forcing evaluation of coercions
  11. Pretty-printing
  12. Tidying
  13. Other
Synopsis

Main data type

datadata Coercion

A Coercion is concrete evidence of the equality/convertibility of two types.

Instances3Data, Outputable, Eq
  • Data CoercionDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.TyCo.Rep
  • Outputable CoercionDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.TyCo.Rep
  • Eq (DeBruijn Coercion)Defined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.Map.Type
datadata CoSel
#
Instances6Eq, Data, Ord, NFData, Outputable, Binary
  • Eq CoSelDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.TyCo.Rep
  • Data CoSelDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.TyCo.Rep
  • Ord CoSelDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.TyCo.Rep
  • NFData CoSelDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.TyCo.Rep
  • Outputable CoSelDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.TyCo.Rep
  • Binary CoSelDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.TyCo.Rep
datadata FunSel
#
Instances5Eq, Data, Ord, NFData, Outputable
  • Eq FunSelDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.TyCo.Rep
  • Data FunSelDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.TyCo.Rep
  • Ord FunSelDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.TyCo.Rep
  • NFData FunSelDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.TyCo.Rep
  • Outputable FunSelDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.TyCo.Rep

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.

Instances6Eq, Data, Ord, NFData, Outputable, Binary
datadata LeftOrRight
#
Instances6Eq, Data, Ord, NFData, Outputable, Binary
datadata Var

Variable

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

Instances13Data, Ord, Uniquable, Outputable, NamedThing, HasOccName, …
  • Eq VarDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Types.Var
  • Data VarDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Types.Var
  • Ord VarDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Types.Var
  • Uniquable VarDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Types.Var
  • Outputable VarDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Types.Var
  • NamedThing VarDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Types.Var
  • OutputableBndr VarDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.Ppr · orphan
  • HasOccName VarDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Types.Var
  • Eq (DeBruijn CoreAlt)Defined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.Map.Expr · orphan
  • Eq (DeBruijn CoreExpr)Defined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.Map.Expr · orphan
  • Eq (DeBruijn Var)Defined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.Map.Type
  • OutputableBndr (Id, TagSig)Defined in ghc-lib-parser-9.14.1.20251220 · GHC.Stg.EnforceEpt.TagSig
  • type Anno Id = SrcSpanAnnNDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Hs.Extension · orphan
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, NFData, Outputable, Binary, …
  • Eq RoleDefined in ghc-lib-parser-9.14.1.20251220 · Language.Haskell.Syntax.Basic
  • Data RoleDefined in ghc-lib-parser-9.14.1.20251220 · Language.Haskell.Syntax.Basic
  • Ord RoleDefined in ghc-lib-parser-9.14.1.20251220 · Language.Haskell.Syntax.Basic
  • NFData RoleDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.Coercion.Axiom · orphan
  • Outputable RoleDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.Coercion.Axiom · orphan
  • Binary RoleDefined in ghc-lib-parser-9.14.1.20251220 · GHC.Core.Coercion.Axiom · orphan
  • type Anno (Maybe Role) = EpAnnCODefined in ghc-lib-parser-9.14.1.20251220 · GHC.Hs.Decls · orphan

Functions over coercions

Constructing coercions

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

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]

Decomposition

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.)

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

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

Tidying

Other

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]

Is there a coercion hole in this type? See wrinkle (DE6) of Note [Defaulting equalities] in GHC.Tc.Solver.Default