Coercion

ghc-7.8.3: 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 Source

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 Source

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 Source

data LeftOrRight Source

Constructors

CLeft |
CRight |

Instances

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

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

data Role Source

Constructors

Nominal |
Representational |
Phantom |

Instances

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

ltRole :: Role -> Role -> Bool Source

## Functions over coercions

coVarKind :: CoVar -> (Type, Type) Source

coVarRole :: CoVar -> Role Source

coercionType :: Coercion -> Type Source

coercionKind :: Coercion -> Pair Type Source

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] Source

Apply `coercionKind` to multiple `Coercion`s

isReflCo :: Coercion -> Bool Source

isReflCo_maybe :: Coercion -> Maybe Type Source

coercionRole :: Coercion -> Role Source

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

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

## Constructing coercions

mkReflCo :: Role -> Type -> Coercion Source

mkCoVarCo :: CoVar -> Coercion Source

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

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

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

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

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

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

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

mkCoCast :: Coercion -> Coercion -> Coercion Source

mkSymCo :: Coercion -> Coercion Source

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 Source

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

mkNthCo :: Int -> Coercion -> Coercion Source

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

mkLRCo :: LeftOrRight -> Coercion -> Coercion Source

mkInstCo :: Coercion -> Type -> Coercion Source

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

mkAppCo :: Coercion -> Coercion -> Coercion Source

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 Source

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

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

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 Source

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

mkForAllCo :: Var -> Coercion -> Coercion Source

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

mkUnsafeCo :: Type -> Type -> Coercion Source

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 Source

mkSubCo :: Coercion -> Coercion Source

mkPhantomCo :: Coercion -> Coercion Source

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

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 Source

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

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

## Decomposition

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

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

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] Source

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 Source

Attempts to obtain the type variable underlying a `Coercion`

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

Attempt to take a coercion application apart.

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

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

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

nextRole :: Coercion -> Role Source

## Coercion variables

mkCoVar :: Name -> Type -> CoVar Source

isCoVar :: Var -> Bool Source

isCoVarType :: Type -> Bool Source

coVarName :: CoVar -> Name Source

setCoVarName :: CoVar -> Name -> CoVar Source

setCoVarUnique :: CoVar -> Unique -> CoVar Source

## Free variables

tyCoVarsOfCo :: Coercion -> VarSet Source

tyCoVarsOfCos :: [Coercion] -> VarSet Source

coVarsOfCo :: Coercion -> VarSet Source

coercionSize :: Coercion -> Int Source

## Substitution

type CvSubstEnv = VarEnv Coercion Source

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

emptyCvSubstEnv :: CvSubstEnv Source

data CvSubst Source

Constructors

CvSubst InScopeSet TvSubstEnv CvSubstEnv |

Instances

Outputable CvSubst |

emptyCvSubst :: CvSubst Source

lookupTyVar :: CvSubst -> TyVar -> Maybe Type Source

lookupCoVar :: CvSubst -> Var -> Maybe Coercion Source

isEmptyCvSubst :: CvSubst -> Bool Source

zapCvSubstEnv :: CvSubst -> CvSubst Source

getCvInScope :: CvSubst -> InScopeSet Source

substCo :: CvSubst -> Coercion -> Coercion Source

Substitute within a `Coercion`

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

Substitute within several `Coercion`s

substCoVar :: CvSubst -> CoVar -> Coercion Source

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

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

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

cvTvSubst :: CvSubst -> TvSubst Source

tvCvSubst :: TvSubst -> CvSubst Source

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

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

substTy :: CvSubst -> Type -> Type Source

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

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

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

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

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

## Lifting

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

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

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

## Comparison

coreEqCoercion :: Coercion -> Coercion -> Bool Source

Determines syntactic equality of coercions

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

## Forcing evaluation of coercions

seqCo :: Coercion -> () Source

# Pretty-printing

pprCo :: Coercion -> SDoc Source

pprParendCo :: Coercion -> SDoc Source

pprCoAxiom :: CoAxiom br -> SDoc Source

pprCoAxBranch :: TyCon -> CoAxBranch -> SDoc Source

pprCoAxBranchHdr :: CoAxiom br -> BranchIndex -> SDoc Source

# Tidying

tidyCo :: TidyEnv -> Coercion -> Coercion Source

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

# Other

applyCo :: Type -> Coercion -> Type Source