ghc-7.8.4: The GHC API

Safe Haskell | None
Language | Haskell98

Coercion

Contents

- Main data type
  - Functions over coercions
  - Constructing coercions
  - Decomposition
  - Coercion variables
  - Free variables
  - Substitution
  - Lifting
  - Comparison
  - Forcing evaluation of coercions
- Pretty-printing
- Tidying
- Other

Description

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.

Synopsis

- data Coercion
  - = Refl Role Type
  - | TyConAppCo Role TyCon [Coercion]
  - | AppCo Coercion Coercion
  - | ForAllCo TyVar Coercion
  - | CoVarCo CoVar
  - | AxiomInstCo (CoAxiom Branched) BranchIndex [Coercion]
  - | UnivCo Role Type Type
  - | SymCo Coercion
  - | TransCo Coercion Coercion
  - | AxiomRuleCo CoAxiomRule [Type] [Coercion]
  - | NthCo Int Coercion
  - | LRCo LeftOrRight Coercion
  - | InstCo Coercion Type
  - | SubCo Coercion
- data Var
- type CoVar = Id
- data LeftOrRight
  - = CLeft
  - | CRight
- pickLR :: LeftOrRight -> (a, a) -> a
- data Role
  - = Nominal
  - | Representational
  - | Phantom
- ltRole :: Role -> Role -> Bool
- coVarKind :: CoVar -> (Type, Type)
- coVarRole :: CoVar -> Role
- coercionType :: Coercion -> Type
- coercionKind :: Coercion -> Pair Type
- coercionKinds :: [Coercion] -> Pair [Type]
- isReflCo :: Coercion -> Bool
- isReflCo_maybe :: Coercion -> Maybe Type
- coercionRole :: Coercion -> Role
- mkCoercionType :: Role -> Type -> Type -> Type
- mkReflCo :: Role -> Type -> Coercion
- mkCoVarCo :: CoVar -> Coercion
- mkAxInstCo :: Role -> CoAxiom br -> BranchIndex -> [Type] -> Coercion
- mkUnbranchedAxInstCo :: Role -> CoAxiom Unbranched -> [Type] -> Coercion
- mkAxInstLHS :: CoAxiom br -> BranchIndex -> [Type] -> Type
- mkAxInstRHS :: CoAxiom br -> BranchIndex -> [Type] -> Type
- mkUnbranchedAxInstRHS :: CoAxiom Unbranched -> [Type] -> Type
- mkPiCo :: Role -> Var -> Coercion -> Coercion
- mkPiCos :: Role -> [Var] -> Coercion -> Coercion
- mkCoCast :: Coercion -> Coercion -> Coercion
- mkSymCo :: Coercion -> Coercion
- mkTransCo :: Coercion -> Coercion -> Coercion
- mkNthCo :: Int -> Coercion -> Coercion
- mkNthCoRole :: Role -> Int -> Coercion -> Coercion
- mkLRCo :: LeftOrRight -> Coercion -> Coercion
- mkInstCo :: Coercion -> Type -> Coercion
- mkAppCo :: Coercion -> Coercion -> Coercion
- mkAppCoFlexible :: Coercion -> Role -> Coercion -> Coercion
- mkTyConAppCo :: Role -> TyCon -> [Coercion] -> Coercion
- mkFunCo :: Role -> Coercion -> Coercion -> Coercion
- mkForAllCo :: Var -> Coercion -> Coercion
- mkUnsafeCo :: Type -> Type -> Coercion
- mkUnivCo :: Role -> Type -> Type -> Coercion
- mkSubCo :: Coercion -> Coercion
- mkPhantomCo :: Coercion -> Coercion
- mkNewTypeCo :: Name -> TyCon -> [TyVar] -> [Role] -> Type -> CoAxiom Unbranched
- maybeSubCo :: Role -> Coercion -> Coercion
- maybeSubCo2 :: Role -> Role -> Coercion -> Coercion
- mkAxiomRuleCo :: CoAxiomRule -> [Type] -> [Coercion] -> Coercion
- instNewTyCon_maybe :: TyCon -> [Type] -> Maybe (Type, Coercion)
- topNormaliseNewType_maybe :: Type -> Maybe (Coercion, Type)
- decomposeCo :: Arity -> Coercion -> [Coercion]
- getCoVar_maybe :: Coercion -> Maybe CoVar
- splitAppCo_maybe :: Coercion -> Maybe (Coercion, Coercion)
- splitForAllCo_maybe :: Coercion -> Maybe (TyVar, Coercion)
- nthRole :: Role -> TyCon -> Int -> Role
- tyConRolesX :: Role -> TyCon -> [Role]
- nextRole :: Coercion -> Role
- mkCoVar :: Name -> Type -> CoVar
- isCoVar :: Var -> Bool
- isCoVarType :: Type -> Bool
- coVarName :: CoVar -> Name
- setCoVarName :: CoVar -> Name -> CoVar
- setCoVarUnique :: CoVar -> Unique -> CoVar
- tyCoVarsOfCo :: Coercion -> VarSet
- tyCoVarsOfCos :: [Coercion] -> VarSet
- coVarsOfCo :: Coercion -> VarSet
- coercionSize :: Coercion -> Int
- type CvSubstEnv = VarEnv Coercion
- emptyCvSubstEnv :: CvSubstEnv
- data CvSubst = CvSubst InScopeSet TvSubstEnv CvSubstEnv
- emptyCvSubst :: CvSubst
- lookupTyVar :: CvSubst -> TyVar -> Maybe Type
- lookupCoVar :: CvSubst -> Var -> Maybe Coercion
- isEmptyCvSubst :: CvSubst -> Bool
- zapCvSubstEnv :: CvSubst -> CvSubst
- getCvInScope :: CvSubst -> InScopeSet
- substCo :: CvSubst -> Coercion -> Coercion
- substCos :: CvSubst -> [Coercion] -> [Coercion]
- substCoVar :: CvSubst -> CoVar -> Coercion
- substCoVars :: CvSubst -> [CoVar] -> [Coercion]
- substCoWithTy :: InScopeSet -> TyVar -> Type -> Coercion -> Coercion
- substCoWithTys :: InScopeSet -> [TyVar] -> [Type] -> Coercion -> Coercion
- cvTvSubst :: CvSubst -> TvSubst
- tvCvSubst :: TvSubst -> CvSubst
- mkCvSubst :: InScopeSet -> [(Var, Coercion)] -> CvSubst
- zipOpenCvSubst :: [Var] -> [Coercion] -> CvSubst
- substTy :: CvSubst -> Type -> Type
- extendTvSubst :: CvSubst -> TyVar -> Type -> CvSubst
- extendCvSubstAndInScope :: CvSubst -> CoVar -> Coercion -> CvSubst
- extendTvSubstAndInScope :: CvSubst -> TyVar -> Type -> CvSubst
- substTyVarBndr :: CvSubst -> TyVar -> (CvSubst, TyVar)
- substCoVarBndr :: CvSubst -> CoVar -> (CvSubst, CoVar)
- liftCoMatch :: TyVarSet -> Type -> Coercion -> Maybe LiftCoSubst
- liftCoSubstTyVar :: LiftCoSubst -> Role -> TyVar -> Maybe Coercion
- liftCoSubstWith :: Role -> [TyVar] -> [Coercion] -> Type -> Coercion
- coreEqCoercion :: Coercion -> Coercion -> Bool
- coreEqCoercion2 :: RnEnv2 -> Coercion -> Coercion -> Bool
- seqCo :: Coercion -> ()
- pprCo :: Coercion -> SDoc
- pprParendCo :: Coercion -> SDoc
- pprCoAxiom :: CoAxiom br -> SDoc
- pprCoAxBranch :: TyCon -> CoAxBranch -> SDoc
- pprCoAxBranchHdr :: CoAxiom br -> BranchIndex -> SDoc
- tidyCo :: TidyEnv -> Coercion -> Coercion
- tidyCos :: TidyEnv -> [Coercion] -> [Coercion]
- applyCo :: Type -> Coercion -> Type

# Main data type

data Coercion

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

Constructors

Refl Role Type |
TyConAppCo Role TyCon [Coercion] |
AppCo Coercion Coercion |
ForAllCo TyVar Coercion |
CoVarCo CoVar |
AxiomInstCo (CoAxiom Branched) BranchIndex [Coercion] |
UnivCo Role Type Type |
SymCo Coercion |
TransCo Coercion Coercion |
AxiomRuleCo CoAxiomRule [Type] [Coercion] |
NthCo Int Coercion |
LRCo LeftOrRight Coercion |
InstCo Coercion Type |
SubCo Coercion |

Instances

Data Coercion |
Outputable Coercion |
Typeable * Coercion |

data Var

Essentially a typed `Name`, that may also contain some additional information about the `Var` and it's use sites.

Instances

Eq Var |
Data Var |
Ord Var |
OutputableBndr Var |
Outputable Var |
Uniquable Var |
NamedThing Var |
Typeable * Var |

type CoVar = Id

data LeftOrRight

Constructors

CLeft |
CRight |

Instances

Eq LeftOrRight |
Data LeftOrRight |
Outputable LeftOrRight |
Binary LeftOrRight |
Typeable * LeftOrRight |

pickLR :: LeftOrRight -> (a, a) -> a

data Role

Constructors

Nominal |
Representational |
Phantom |

Instances

Eq Role |
Data Role |
Outputable Role |
Binary Role |
Typeable * Role |

ltRole :: Role -> Role -> Bool

## Functions over coercions

coVarKind :: CoVar -> (Type, Type)

coVarRole :: CoVar -> Role

coercionType :: Coercion -> Type

coercionKind :: Coercion -> Pair Type

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

coercionKinds :: [Coercion] -> Pair [Type]

Apply `coercionKind` to multiple `Coercion`s

isReflCo :: Coercion -> Bool

isReflCo_maybe :: Coercion -> Maybe Type

coercionRole :: Coercion -> Role

mkCoercionType :: Role -> Type -> Type -> Type

Makes a coercion type from two types: the types whose equality is proven by the relevant `Coercion`

## Constructing coercions

mkReflCo :: Role -> Type -> Coercion

mkCoVarCo :: CoVar -> Coercion

mkAxInstCo :: Role -> CoAxiom br -> BranchIndex -> [Type] -> Coercion

mkUnbranchedAxInstCo :: Role -> CoAxiom Unbranched -> [Type] -> Coercion

mkAxInstLHS :: CoAxiom br -> BranchIndex -> [Type] -> Type

mkAxInstRHS :: CoAxiom br -> BranchIndex -> [Type] -> Type

mkUnbranchedAxInstRHS :: CoAxiom Unbranched -> [Type] -> Type

mkPiCo :: Role -> Var -> Coercion -> Coercion

mkPiCos :: Role -> [Var] -> Coercion -> Coercion

mkCoCast :: Coercion -> Coercion -> Coercion

mkSymCo :: 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`.

mkTransCo :: Coercion -> Coercion -> Coercion

Create a new `Coercion` by composing the two given `Coercion`s transitively.

mkNthCo :: Int -> Coercion -> Coercion

mkNthCoRole :: Role -> Int -> Coercion -> Coercion

mkLRCo :: LeftOrRight -> Coercion -> Coercion

mkInstCo :: Coercion -> Type -> Coercion

Instantiates a `Coercion` with a `Type` argument.

mkAppCo :: Coercion -> Coercion -> Coercion

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.

mkAppCoFlexible :: Coercion -> Role -> Coercion -> Coercion

Apply a `Coercion` to another `Coercion`. The second `Coercion`s role is given, making this more flexible than `mkAppCo`.

mkTyConAppCo :: Role -> TyCon -> [Coercion] -> Coercion

Apply a type constructor to a list of coercions. It is the caller's responsibility to get the roles correct on argument coercions.

mkFunCo :: Role -> Coercion -> Coercion -> Coercion

Make a function `Coercion` between two other `Coercion`s

mkForAllCo :: Var -> Coercion -> Coercion

Make a `Coercion` which binds a variable within an inner `Coercion`

mkUnsafeCo :: Type -> Type -> Coercion

Manufacture a coercion from thin air. Needless to say, this is not usually safe, but it is used when we know we are dealing with bottom, which is one case in which it is safe. This is also used to implement the `unsafeCoerce#` primitive. Optimise by pushing down through type constructors.

mkUnivCo :: Role -> Type -> Type -> Coercion

mkSubCo :: Coercion -> Coercion

mkPhantomCo :: Coercion -> Coercion

mkNewTypeCo :: Name -> TyCon -> [TyVar] -> [Role] -> Type -> CoAxiom Unbranched

Create a coercion constructor (axiom) suitable for the given newtype `TyCon`. The `Name` should be that of a new coercion `CoAxiom`, the `TyVar`s the arguments expected by the `newtype` and the type the appropriate right hand side of the `newtype`, with the free variables a subset of those `TyVar`s.

maybeSubCo :: Role -> Coercion -> Coercion

maybeSubCo2 :: Role -> Role -> Coercion -> Coercion

mkAxiomRuleCo :: CoAxiomRule -> [Type] -> [Coercion] -> Coercion

## Decomposition

instNewTyCon_maybe :: TyCon -> [Type] -> Maybe (Type, Coercion)

If `co :: T ts ~ rep_ty` then:

    instNewTyCon_maybe T ts = Just (rep_ty, co)

Checks for a newtype, and for being saturated

topNormaliseNewType_maybe :: Type -> Maybe (Coercion, Type)

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 : ty0 ~ 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

decomposeCo :: Arity -> Coercion -> [Coercion]

This breaks a `Coercion` with type `T A B C ~ T D E F` into a list of `Coercion`s of kinds `A ~ D`, `B ~ E` and `E ~ F`. Hence:

    decomposeCo 3 c = [nth 0 c, nth 1 c, nth 2 c]

getCoVar_maybe :: Coercion -> Maybe CoVar

Attempts to obtain the type variable underlying a `Coercion`

splitAppCo_maybe :: Coercion -> Maybe (Coercion, Coercion)

Attempt to take a coercion application apart.

splitForAllCo_maybe :: Coercion -> Maybe (TyVar, Coercion)

nthRole :: Role -> TyCon -> Int -> Role

tyConRolesX :: Role -> TyCon -> [Role]

nextRole :: Coercion -> Role

## Coercion variables

mkCoVar :: Name -> Type -> CoVar

isCoVar :: Var -> Bool

isCoVarType :: Type -> Bool

coVarName :: CoVar -> Name

setCoVarName :: CoVar -> Name -> CoVar

setCoVarUnique :: CoVar -> Unique -> CoVar

## Free variables

tyCoVarsOfCo :: Coercion -> VarSet

tyCoVarsOfCos :: [Coercion] -> VarSet

coVarsOfCo :: Coercion -> VarSet

coercionSize :: Coercion -> Int

## Substitution

type CvSubstEnv = VarEnv Coercion

A substitution of `Coercion`s for `CoVar`s (OR `TyVar`s, when doing a "lifting" substitution)

emptyCvSubstEnv :: CvSubstEnv

data CvSubst

Constructors

CvSubst InScopeSet TvSubstEnv CvSubstEnv |

Instances

Outputable CvSubst |

emptyCvSubst :: CvSubst

lookupTyVar :: CvSubst -> TyVar -> Maybe Type

lookupCoVar :: CvSubst -> Var -> Maybe Coercion

isEmptyCvSubst :: CvSubst -> Bool

zapCvSubstEnv :: CvSubst -> CvSubst

getCvInScope :: CvSubst -> InScopeSet

substCo :: CvSubst -> Coercion -> Coercion

Substitute within a `Coercion`

substCos :: CvSubst -> [Coercion] -> [Coercion]

Substitute within several `Coercion`s

substCoVar :: CvSubst -> CoVar -> Coercion

substCoVars :: CvSubst -> [CoVar] -> [Coercion]

substCoWithTy :: InScopeSet -> TyVar -> Type -> Coercion -> Coercion

substCoWithTys :: InScopeSet -> [TyVar] -> [Type] -> Coercion -> Coercion

cvTvSubst :: CvSubst -> TvSubst

tvCvSubst :: TvSubst -> CvSubst

mkCvSubst :: InScopeSet -> [(Var, Coercion)] -> CvSubst

zipOpenCvSubst :: [Var] -> [Coercion] -> CvSubst

substTy :: CvSubst -> Type -> Type

extendTvSubst :: CvSubst -> TyVar -> Type -> CvSubst

extendCvSubstAndInScope :: CvSubst -> CoVar -> Coercion -> CvSubst

extendTvSubstAndInScope :: CvSubst -> TyVar -> Type -> CvSubst

substTyVarBndr :: CvSubst -> TyVar -> (CvSubst, TyVar)

substCoVarBndr :: CvSubst -> CoVar -> (CvSubst, CoVar)

## Lifting

liftCoMatch :: TyVarSet -> Type -> Coercion -> Maybe LiftCoSubst

`liftCoMatch` is sort of inverse to `liftCoSubst`. In particular, if `liftCoMatch vars ty co == Just s`, then `tyCoSubst s ty == co`. That is, it matches a type against a coercion of the same "shape", and returns a lifting substitution which could have been used to produce the given coercion from the given type.

liftCoSubstTyVar :: LiftCoSubst -> Role -> TyVar -> Maybe Coercion

liftCoSubstWith :: Role -> [TyVar] -> [Coercion] -> Type -> Coercion

## Comparison

coreEqCoercion :: Coercion -> Coercion -> Bool

Determines syntactic equality of coercions

coreEqCoercion2 :: RnEnv2 -> Coercion -> Coercion -> Bool

## Forcing evaluation of coercions

seqCo :: Coercion -> ()

# Pretty-printing

pprCo :: Coercion -> SDoc

pprParendCo :: Coercion -> SDoc

pprCoAxiom :: CoAxiom br -> SDoc

pprCoAxBranch :: TyCon -> CoAxBranch -> SDoc

pprCoAxBranchHdr :: CoAxiom br -> BranchIndex -> SDoc

# Tidying

tidyCo :: TidyEnv -> Coercion -> Coercion

tidyCos :: TidyEnv -> [Coercion] -> [Coercion]

# Other

applyCo :: Type -> Coercion -> Type