Coercion

ghc-7.10.2: The GHC API

Safe Haskell | None
Language | Haskell2010

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 FastString 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
- coercionKindRole :: Coercion -> (Pair Type, 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 :: FastString -> Role -> Type -> Type -> Coercion
- mkSubCo :: Coercion -> Coercion
- mkPhantomCo :: Coercion -> Coercion
- mkNewTypeCo :: Name -> TyCon -> [TyVar] -> [Role] -> Type -> CoAxiom Unbranched
- downgradeRole :: Role -> Role -> Coercion -> Coercion
- mkAxiomRuleCo :: CoAxiomRule -> [Type] -> [Coercion] -> Coercion
- instNewTyCon_maybe :: TyCon -> [Type] -> Maybe (Type, Coercion)
- type NormaliseStepper = RecTcChecker -> TyCon -> [Type] -> NormaliseStepResult
- data NormaliseStepResult
  - = NS_Done
  - | NS_Abort
  - | NS_Step RecTcChecker Type Coercion
- composeSteppers :: NormaliseStepper -> NormaliseStepper -> NormaliseStepper
- modifyStepResultCo :: (Coercion -> Coercion) -> NormaliseStepResult -> NormaliseStepResult
- unwrapNewTypeStepper :: NormaliseStepper
- topNormaliseNewType_maybe :: Type -> Maybe (Coercion, Type)
- topNormaliseTypeX_maybe :: NormaliseStepper -> 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]
- setNominalRole_maybe :: Coercion -> Maybe Coercion
- 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 FastString 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 |

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 |
Outputable Var |
Uniquable Var |
NamedThing Var |
type PostRn Id ty = ty |
type PostTc Id ty = ty |

type CoVar = Id Source

data LeftOrRight Source

Constructors

CLeft |
CRight |

Instances

Eq LeftOrRight |
Data LeftOrRight |
Outputable LeftOrRight |
Binary LeftOrRight |

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

data Role Source

Constructors

Nominal |
Representational |
Phantom |

Instances

Eq Role |
Data Role |
Outputable Role |
Binary 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

Retrieve the role from a coercion.

coercionKindRole :: Coercion -> (Pair Type, Role) Source

Get a coercion's kind and role. Why both at once? See Note [Computing a coercion kind and role]

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 an unsafe coercion from thin air. Currently (May 14) this is used only to implement the `unsafeCoerce#` primitive. Optimise by pushing down through type constructors.

mkUnivCo :: FastString -> 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.

downgradeRole :: 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

type NormaliseStepper = RecTcChecker -> TyCon -> [Type] -> NormaliseStepResult Source

A function to check if we can reduce a type by one step. Used with `topNormaliseTypeX_maybe`.

data NormaliseStepResult Source

The result of stepping in a normalisation function. See `topNormaliseTypeX_maybe`.

Constructors

NS_Done | nothing more to do
NS_Abort | utter failure. The outer function should fail too.
NS_Step RecTcChecker Type Coercion | we stepped, yielding new bits; ^ co :: old type ~ new type

composeSteppers :: NormaliseStepper -> NormaliseStepper -> NormaliseStepper Source

Try one stepper and then try the next, if the first doesn't make progress.

modifyStepResultCo :: (Coercion -> Coercion) -> NormaliseStepResult -> NormaliseStepResult Source

unwrapNewTypeStepper :: NormaliseStepper Source

A `NormaliseStepper` that unwraps newtypes, careful not to fall into a loop. If it would fall into a loop, it produces `NS_Abort`.

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`, or responds False to ok_tc. Specifically, here's the invariant:

    topNormaliseNewType_maybe 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

topNormaliseTypeX_maybe :: NormaliseStepper -> Type -> Maybe (Coercion, Type) Source

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_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

setNominalRole_maybe :: Coercion -> Maybe Coercion 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