Safe Haskell | None |
---|---|
Language | Haskell2010 |
Coercion
Contents
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.
- data Coercion
- type CoercionN = Coercion
- type CoercionR = Coercion
- type CoercionP = Coercion
- data UnivCoProvenance
- data CoercionHole
- data LeftOrRight
- data Var
- type CoVar = Id
- type TyCoVar = Id
- data Role
- ltRole :: Role -> Role -> Bool
- coVarTypes :: CoVar -> (Type, Type)
- coVarKind :: CoVar -> Type
- coVarKindsTypesRole :: CoVar -> (Kind, Kind, Type, Type, Role)
- coVarRole :: CoVar -> Role
- coercionType :: Coercion -> Type
- coercionKind :: Coercion -> Pair Type
- coercionKinds :: [Coercion] -> Pair [Type]
- mkCoercionType :: Role -> Type -> Type -> Type
- coercionRole :: Coercion -> Role
- coercionKindRole :: Coercion -> (Pair Type, Role)
- mkReflCo :: Role -> Type -> Coercion
- mkRepReflCo :: Type -> Coercion
- mkNomReflCo :: Type -> Coercion
- mkCoVarCo :: CoVar -> Coercion
- mkCoVarCos :: [CoVar] -> [Coercion]
- mkAxInstCo :: Role -> CoAxiom br -> BranchIndex -> [Type] -> [Coercion] -> Coercion
- mkUnbranchedAxInstCo :: Role -> CoAxiom Unbranched -> [Type] -> [Coercion] -> Coercion
- mkAxInstRHS :: CoAxiom br -> BranchIndex -> [Type] -> [Coercion] -> Type
- mkUnbranchedAxInstRHS :: CoAxiom Unbranched -> [Type] -> [Coercion] -> Type
- mkAxInstLHS :: CoAxiom br -> BranchIndex -> [Type] -> [Coercion] -> Type
- mkUnbranchedAxInstLHS :: CoAxiom Unbranched -> [Type] -> [Coercion] -> Type
- mkPiCo :: Role -> Var -> Coercion -> Coercion
- mkPiCos :: Role -> [Var] -> Coercion -> Coercion
- mkCoCast :: Coercion -> Coercion -> Coercion
- mkSymCo :: Coercion -> Coercion
- mkTransCo :: Coercion -> Coercion -> Coercion
- mkTransAppCo :: Role -> Coercion -> Type -> Type -> Role -> Coercion -> Type -> Type -> Role -> Coercion
- mkNthCo :: Int -> Coercion -> Coercion
- mkNthCoRole :: Role -> Int -> Coercion -> Coercion
- mkLRCo :: LeftOrRight -> Coercion -> Coercion
- mkInstCo :: Coercion -> Coercion -> Coercion
- mkAppCo :: Coercion -> Coercion -> Coercion
- mkAppCos :: Coercion -> [Coercion] -> Coercion
- mkTyConAppCo :: Role -> TyCon -> [Coercion] -> Coercion
- mkFunCo :: Role -> Coercion -> Coercion -> Coercion
- mkFunCos :: Role -> [Coercion] -> Coercion -> Coercion
- mkForAllCo :: TyVar -> Coercion -> Coercion -> Coercion
- mkForAllCos :: [(TyVar, Coercion)] -> Coercion -> Coercion
- mkHomoForAllCos :: [TyVar] -> Coercion -> Coercion
- mkHomoForAllCos_NoRefl :: [TyVar] -> Coercion -> Coercion
- mkPhantomCo :: Coercion -> Type -> Type -> Coercion
- mkHomoPhantomCo :: Type -> Type -> Coercion
- toPhantomCo :: Coercion -> Coercion
- mkUnsafeCo :: Role -> Type -> Type -> Coercion
- mkHoleCo :: CoercionHole -> Role -> Type -> Type -> Coercion
- mkUnivCo :: UnivCoProvenance -> Role -> Type -> Type -> Coercion
- mkSubCo :: Coercion -> Coercion
- mkAxiomInstCo :: CoAxiom Branched -> BranchIndex -> [Coercion] -> Coercion
- mkProofIrrelCo :: Role -> Coercion -> Coercion -> Coercion -> Coercion
- downgradeRole :: Role -> Role -> Coercion -> Coercion
- maybeSubCo :: EqRel -> Coercion -> Coercion
- mkAxiomRuleCo :: CoAxiomRule -> [Coercion] -> Coercion
- mkCoherenceCo :: Coercion -> Coercion -> Coercion
- mkCoherenceRightCo :: Coercion -> Coercion -> Coercion
- mkCoherenceLeftCo :: Coercion -> Coercion -> Coercion
- mkKindCo :: Coercion -> Coercion
- castCoercionKind :: Coercion -> Coercion -> Coercion -> Coercion
- mkHeteroCoercionType :: Role -> Kind -> Kind -> Type -> Type -> Type
- instNewTyCon_maybe :: TyCon -> [Type] -> Maybe (Type, Coercion)
- type NormaliseStepper = RecTcChecker -> TyCon -> [Type] -> NormaliseStepResult
- data NormaliseStepResult
- 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
- splitTyConAppCo_maybe :: Coercion -> Maybe (TyCon, [Coercion])
- splitAppCo_maybe :: Coercion -> Maybe (Coercion, Coercion)
- splitForAllCo_maybe :: Coercion -> Maybe (TyVar, Coercion, Coercion)
- nthRole :: Role -> TyCon -> Int -> Role
- tyConRolesX :: Role -> TyCon -> [Role]
- setNominalRole_maybe :: Coercion -> Maybe Coercion
- pickLR :: LeftOrRight -> (a, a) -> a
- isReflCo :: Coercion -> Bool
- isReflCo_maybe :: Coercion -> Maybe (Type, Role)
- isReflexiveCo :: Coercion -> Bool
- isReflexiveCo_maybe :: Coercion -> Maybe (Type, Role)
- mkCoVar :: Name -> Type -> CoVar
- isCoVar :: Var -> Bool
- coVarName :: CoVar -> Name
- setCoVarName :: CoVar -> Name -> CoVar
- setCoVarUnique :: CoVar -> Unique -> CoVar
- isCoVar_maybe :: Coercion -> Maybe CoVar
- tyCoVarsOfCo :: Coercion -> TyCoVarSet
- tyCoVarsOfCos :: [Coercion] -> TyCoVarSet
- coVarsOfCo :: Coercion -> CoVarSet
- tyCoVarsOfCoAcc :: Coercion -> FV
- tyCoVarsOfCosAcc :: [Coercion] -> FV
- tyCoVarsOfCoDSet :: Coercion -> DTyCoVarSet
- coercionSize :: Coercion -> Int
- type CvSubstEnv = CoVarEnv Coercion
- emptyCvSubstEnv :: CvSubstEnv
- lookupCoVar :: TCvSubst -> Var -> Maybe Coercion
- substCo :: TCvSubst -> Coercion -> Coercion
- substCos :: TCvSubst -> [Coercion] -> [Coercion]
- substCoVar :: TCvSubst -> CoVar -> Coercion
- substCoVars :: TCvSubst -> [CoVar] -> [Coercion]
- substCoWith :: [TyVar] -> [Type] -> Coercion -> Coercion
- substCoVarBndr :: TCvSubst -> CoVar -> (TCvSubst, CoVar)
- extendTCvSubstAndInScope :: TCvSubst -> TyCoVar -> Type -> TCvSubst
- getCvSubstEnv :: TCvSubst -> CvSubstEnv
- liftCoSubst :: Role -> LiftingContext -> Type -> Coercion
- liftCoSubstTyVar :: LiftingContext -> Role -> TyVar -> Maybe Coercion
- liftCoSubstWith :: Role -> [TyCoVar] -> [Coercion] -> Type -> Coercion
- liftCoSubstWithEx :: Role -> [TyVar] -> [Coercion] -> [TyVar] -> [Type] -> (Type -> Coercion, [Type])
- emptyLiftingContext :: InScopeSet -> LiftingContext
- extendLiftingContext :: LiftingContext -> TyVar -> Coercion -> LiftingContext
- liftCoSubstVarBndrCallback :: (LiftingContext -> Type -> (Coercion, a)) -> LiftingContext -> TyVar -> (LiftingContext, TyVar, Coercion, a)
- isMappedByLC :: TyCoVar -> LiftingContext -> Bool
- mkSubstLiftingContext :: TCvSubst -> LiftingContext
- zapLiftingContext :: LiftingContext -> LiftingContext
- substForAllCoBndrCallbackLC :: Bool -> (Coercion -> Coercion) -> LiftingContext -> TyVar -> Coercion -> (LiftingContext, TyVar, Coercion)
- lcTCvSubst :: LiftingContext -> TCvSubst
- lcInScopeSet :: LiftingContext -> InScopeSet
- type LiftCoEnv = VarEnv Coercion
- data LiftingContext = LC TCvSubst LiftCoEnv
- liftEnvSubstLeft :: TCvSubst -> LiftCoEnv -> TCvSubst
- liftEnvSubstRight :: TCvSubst -> LiftCoEnv -> TCvSubst
- substRightCo :: LiftingContext -> Coercion -> Coercion
- substLeftCo :: LiftingContext -> Coercion -> Coercion
- swapLiftCoEnv :: LiftCoEnv -> LiftCoEnv
- lcSubstLeft :: LiftingContext -> TCvSubst
- lcSubstRight :: LiftingContext -> TCvSubst
- eqCoercion :: Coercion -> Coercion -> Bool
- eqCoercionX :: RnEnv2 -> Coercion -> Coercion -> Bool
- seqCo :: Coercion -> ()
- pprCo :: Coercion -> SDoc
- pprParendCo :: Coercion -> SDoc
- pprCoBndr :: Name -> Coercion -> SDoc
- pprCoAxiom :: CoAxiom br -> SDoc
- pprCoAxBranch :: CoAxiom br -> CoAxBranch -> SDoc
- pprCoAxBranchHdr :: CoAxiom br -> BranchIndex -> SDoc
- tidyCo :: TidyEnv -> Coercion -> Coercion
- tidyCos :: TidyEnv -> [Coercion] -> [Coercion]
- promoteCoercion :: Coercion -> Coercion
Main data type
data 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
.
Instances
data LeftOrRight
Instances
data Var
data Role
Constructors
Nominal | |
Representational | |
Phantom |
Functions over coercions
coVarTypes :: CoVar -> (Type, Type)
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
mkCoercionType :: Role -> Type -> Type -> Type
Makes a coercion type from two types: the types whose equality
is proven by the relevant Coercion
coercionRole :: Coercion -> Role
Retrieve the role from a coercion.
coercionKindRole :: Coercion -> (Pair Type, Role)
Get a coercion's kind and role. Why both at once? See Note [Computing a coercion kind and role]
Constructing coercions
mkRepReflCo :: Type -> Coercion
Make a representational reflexive coercion
mkNomReflCo :: Type -> Coercion
Make a nominal reflexive coercion
mkCoVarCos :: [CoVar] -> [Coercion]
mkAxInstCo :: Role -> CoAxiom br -> BranchIndex -> [Type] -> [Coercion] -> Coercion
mkUnbranchedAxInstCo :: Role -> CoAxiom Unbranched -> [Type] -> [Coercion] -> Coercion
mkAxInstRHS :: CoAxiom br -> BranchIndex -> [Type] -> [Coercion] -> Type
mkUnbranchedAxInstRHS :: CoAxiom Unbranched -> [Type] -> [Coercion] -> Type
mkAxInstLHS :: CoAxiom br -> BranchIndex -> [Type] -> [Coercion] -> Type
Return the left-hand type of the axiom, when the axiom is instantiated at the types given.
mkUnbranchedAxInstLHS :: CoAxiom Unbranched -> [Type] -> [Coercion] -> Type
Instantiate the left-hand side of an unbranched axiom
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
.
Arguments
:: Role | r1 |
-> Coercion | co1 :: ty1a ~r1 ty1b |
-> Type | ty1a |
-> Type | ty1b |
-> Role | r2 |
-> Coercion | co2 :: ty2a ~r2 ty2b |
-> Type | ty2a |
-> Type | ty2b |
-> Role | r3 |
-> Coercion | :: ty1a ty2a ~r3 ty1b ty2b |
Like mkAppCo
, but allows the second coercion to be other than
nominal. See Note [mkTransAppCo]. Role r3 cannot be more stringent
than either r1 or r2.
mkNthCoRole :: Role -> Int -> Coercion -> Coercion
mkLRCo :: LeftOrRight -> Coercion -> Coercion
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.
mkForAllCo :: TyVar -> Coercion -> Coercion -> Coercion
Make a Coercion from a tyvar, a kind coercion, and a body coercion. The kind of the tyvar should be the left-hand kind of the kind coercion.
mkForAllCos :: [(TyVar, Coercion)] -> Coercion -> Coercion
Make nested ForAllCos
mkHomoForAllCos :: [TyVar] -> Coercion -> Coercion
Make a Coercion quantified over a type variable; the variable has the same type in both sides of the coercion
mkHomoForAllCos_NoRefl :: [TyVar] -> Coercion -> Coercion
Like mkHomoForAllCos
, but doesn't check if the inner coercion
is reflexive.
mkPhantomCo :: 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.
mkHomoPhantomCo :: Type -> Type -> Coercion
Make a phantom coercion between two types of the same kind.
toPhantomCo :: Coercion -> Coercion
mkUnsafeCo :: Role -> Type -> Type -> Coercion
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.
Arguments
:: UnivCoProvenance | |
-> Role | role of the built coercion, "r" |
-> Type | t1 :: k1 |
-> Type | t2 :: k2 |
-> Coercion | :: t1 ~r t2 |
Make a universal coercion between two arbitrary types.
mkAxiomInstCo :: CoAxiom Branched -> BranchIndex -> [Coercion] -> Coercion
Arguments
:: Role | role of the created coercion, "r" |
-> Coercion | :: phi1 ~N phi2 |
-> Coercion | g1 :: phi1 |
-> Coercion | g2 :: phi2 |
-> Coercion | :: g1 ~r g2 |
Make a "coercion between coercions".
downgradeRole :: Role -> Role -> Coercion -> Coercion
Like downgradeRole_maybe
, but panics if the change isn't a downgrade.
See Note [Role twiddling functions]
maybeSubCo :: EqRel -> Coercion -> Coercion
If the EqRel is ReprEq, makes a SubCo; otherwise, does nothing. Note that the input coercion should always be nominal.
mkAxiomRuleCo :: CoAxiomRule -> [Coercion] -> Coercion
mkCoherenceCo :: Coercion -> Coercion -> Coercion infixl 5
mkCoherenceRightCo :: Coercion -> Coercion -> Coercion infixl 5
A CoherenceCo c1 c2 applies the coercion c2 to the left-hand type in the kind of c1. This function uses sym to get the coercion on the right-hand type of c1. Thus, if c1 :: s ~ t, then mkCoherenceRightCo c1 c2 has the kind (s ~ (t |> c2)) down through type constructors. The second coercion must be representational.
mkCoherenceLeftCo :: Coercion -> Coercion -> Coercion infixl 5
An explictly directed synonym of mkCoherenceCo. The second coercion must be representational.
castCoercionKind :: Coercion -> Coercion -> Coercion -> Coercion
Creates a new coercion with both of its types casted by different casts castCoercionKind g h1 h2, where g :: t1 ~ t2, has type (t1 |> h1) ~ (t2 |> h2) The second and third coercions must be nominal.
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
type NormaliseStepper = RecTcChecker -> TyCon -> [Type] -> NormaliseStepResult
A function to check if we can reduce a type by one step. Used
with topNormaliseTypeX_maybe
.
data NormaliseStepResult
The result of stepping in a normalisation function.
See topNormaliseTypeX_maybe
.
composeSteppers :: NormaliseStepper -> NormaliseStepper -> NormaliseStepper
Try one stepper and then try the next, if the first doesn't make progress. So if it returns NS_Done, it means that both steppers are satisfied
modifyStepResultCo :: (Coercion -> Coercion) -> NormaliseStepResult -> NormaliseStepResult
unwrapNewTypeStepper :: NormaliseStepper
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)
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
topNormaliseTypeX_maybe :: NormaliseStepper -> Type -> Maybe (Coercion, 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_maybe
.
decomposeCo :: Arity -> Coercion -> [Coercion]
getCoVar_maybe :: Coercion -> Maybe CoVar
Attempts to obtain the type variable underlying a Coercion
splitTyConAppCo_maybe :: Coercion -> Maybe (TyCon, [Coercion])
Attempts to tease a coercion apart into a type constructor and the application of a number of coercion arguments to that constructor
splitAppCo_maybe :: Coercion -> Maybe (Coercion, Coercion)
Attempt to take a coercion application apart.
tyConRolesX :: Role -> TyCon -> [Role]
setNominalRole_maybe :: Coercion -> Maybe Coercion
Converts a coercion to be nominal, if possible. See Note [Role twiddling functions]
pickLR :: LeftOrRight -> (a, a) -> a
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
isReflCo_maybe :: Coercion -> Maybe (Type, Role)
Returns the type coerced if this coercion is reflexive. Guaranteed
to work very quickly. Sometimes a coercion can be reflexive, but not
obviously so. c.f. isReflexiveCo_maybe
isReflexiveCo :: Coercion -> Bool
Slowly checks if the coercion is reflexive. Don't call this in a loop, as it walks over the entire coercion.
isReflexiveCo_maybe :: Coercion -> Maybe (Type, Role)
Extracts the coerced type from a reflexive coercion. This potentially walks over the entire coercion, so avoid doing this in a loop.
Coercion variables
setCoVarName :: CoVar -> Name -> CoVar
setCoVarUnique :: CoVar -> Unique -> CoVar
isCoVar_maybe :: Coercion -> Maybe CoVar
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.)
Free variables
tyCoVarsOfCo :: Coercion -> TyCoVarSet
tyCoVarsOfCos :: [Coercion] -> TyCoVarSet
coVarsOfCo :: Coercion -> CoVarSet
tyCoVarsOfCoAcc :: Coercion -> FV
tyCoVarsOfCosAcc :: [Coercion] -> FV
tyCoVarsOfCoDSet :: Coercion -> DTyCoVarSet
Get a deterministic set of the vars free in a coercion
coercionSize :: Coercion -> Int
Substitution
type CvSubstEnv = CoVarEnv Coercion
lookupCoVar :: TCvSubst -> Var -> Maybe Coercion
substCoVar :: TCvSubst -> CoVar -> Coercion
substCoVars :: TCvSubst -> [CoVar] -> [Coercion]
substCoWith :: [TyVar] -> [Type] -> Coercion -> Coercion
Coercion substitution, see zipTvSubst
substCoVarBndr :: TCvSubst -> CoVar -> (TCvSubst, CoVar)
extendTCvSubstAndInScope :: TCvSubst -> TyCoVar -> Type -> TCvSubst
getCvSubstEnv :: TCvSubst -> CvSubstEnv
Lifting
liftCoSubst :: Role -> LiftingContext -> Type -> Coercion
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
.
liftCoSubstTyVar :: LiftingContext -> Role -> TyVar -> Maybe Coercion
liftCoSubstWithEx :: Role -> [TyVar] -> [Coercion] -> [TyVar] -> [Type] -> (Type -> Coercion, [Type])
Arguments
:: LiftingContext | original LC |
-> TyVar | new variable to map... |
-> Coercion | ...to this lifted version |
-> LiftingContext |
Extend a lifting context with a new type mapping.
liftCoSubstVarBndrCallback :: (LiftingContext -> Type -> (Coercion, a)) -> LiftingContext -> TyVar -> (LiftingContext, TyVar, Coercion, a)
isMappedByLC :: TyCoVar -> LiftingContext -> Bool
Is a var in the domain of a lifting context?
zapLiftingContext :: LiftingContext -> LiftingContext
Erase the environments in a lifting context
substForAllCoBndrCallbackLC :: Bool -> (Coercion -> Coercion) -> LiftingContext -> TyVar -> Coercion -> (LiftingContext, TyVar, Coercion)
Like substForAllCoBndr
, but works on a lifting context
lcTCvSubst :: LiftingContext -> TCvSubst
Extract the underlying substitution from the LiftingContext
lcInScopeSet :: LiftingContext -> InScopeSet
Get the InScopeSet
from a LiftingContext
liftEnvSubstLeft :: TCvSubst -> LiftCoEnv -> TCvSubst
liftEnvSubstRight :: TCvSubst -> LiftCoEnv -> TCvSubst
substRightCo :: LiftingContext -> Coercion -> Coercion
substLeftCo :: LiftingContext -> Coercion -> Coercion
swapLiftCoEnv :: LiftCoEnv -> LiftCoEnv
Apply "sym" to all coercions in a LiftCoEnv
Comparison
eqCoercion :: Coercion -> Coercion -> Bool
Syntactic equality of coercions
eqCoercionX :: RnEnv2 -> Coercion -> Coercion -> Bool
Compare two Coercion
s, with respect to an RnEnv2
Forcing evaluation of coercions
Pretty-printing
pprParendCo :: Coercion -> SDoc
pprCoAxiom :: CoAxiom br -> SDoc
pprCoAxBranch :: CoAxiom br -> CoAxBranch -> SDoc
pprCoAxBranchHdr :: CoAxiom br -> BranchIndex -> SDoc
Tidying
Other
promoteCoercion :: Coercion -> Coercion
like mkKindCo, but aggressively & recursively optimizes to avoid using a KindCo constructor. The output role is nominal.