ghc-8.2.2: The GHC API

Safe Haskell | None
Language | Haskell2010

Unify

Contents

- Rough matching

Synopsis

- tcMatchTy :: Type -> Type -> Maybe TCvSubst
- tcMatchTyKi :: Type -> Type -> Maybe TCvSubst
- tcMatchTys :: [Type] -> [Type] -> Maybe TCvSubst
- tcMatchTyKis :: [Type] -> [Type] -> Maybe TCvSubst
- tcMatchTyX :: TCvSubst -> Type -> Type -> Maybe TCvSubst
- tcMatchTysX :: TCvSubst -> [Type] -> [Type] -> Maybe TCvSubst
- tcMatchTyKisX :: TCvSubst -> [Type] -> [Type] -> Maybe TCvSubst
- ruleMatchTyKiX :: TyCoVarSet -> RnEnv2 -> TvSubstEnv -> Type -> Type -> Maybe TvSubstEnv
- roughMatchTcs :: [Type] -> [Maybe Name]
- instanceCantMatch :: [Maybe Name] -> [Maybe Name] -> Bool
- typesCantMatch :: [(Type, Type)] -> Bool
- tcUnifyTy :: Type -> Type -> Maybe TCvSubst
- tcUnifyTyKi :: Type -> Type -> Maybe TCvSubst
- tcUnifyTys :: (TyCoVar -> BindFlag) -> [Type] -> [Type] -> Maybe TCvSubst
- tcUnifyTyKis :: (TyCoVar -> BindFlag) -> [Type] -> [Type] -> Maybe TCvSubst
- tcUnifyTysFG :: (TyVar -> BindFlag) -> [Type] -> [Type] -> UnifyResult
- tcUnifyTyWithTFs :: Bool -> Type -> Type -> Maybe TCvSubst
- data BindFlag
  - = BindMe
  - | Skolem
- type UnifyResult = UnifyResultM TCvSubst
- data UnifyResultM a
  - = Unifiable a
  - | MaybeApart a
  - | SurelyApart
- liftCoMatch :: TyCoVarSet -> Type -> Coercion -> Maybe LiftingContext

# Documentation

tcMatchTy :: Type -> Type -> Maybe TCvSubst #

`tcMatchTy t1 t2` produces a substitution (over fvs(t1)) `s` such that `s(t1)` equals `t2`. The returned substitution might bind coercion variables, if the variable is an argument to a GADT constructor.

Precondition: typeKind ty1 `eqType` typeKind ty2

We don't pass in a set of "template variables" to be bound by the match, because tcMatchTy (and similar functions) are always used on top-level types, so we can bind any of the free variables of the LHS.

tcMatchTyKi :: Type -> Type -> Maybe TCvSubst #

Like `tcMatchTy`, but allows the kinds of the types to differ, and thus matches them as well.

tcMatchTys #

Arguments

:: [Type] | Template
-> [Type] | Target
-> Maybe TCvSubst | One-shot; in principle the template variables could be free in the target

Like `tcMatchTy` but over a list of types.

tcMatchTyKis #

Arguments

:: [Type] | Template
-> [Type] | Target
-> Maybe TCvSubst | One-shot substitution

Like `tcMatchTyKi` but over a list of types.

tcMatchTyX #

Arguments

:: TCvSubst | Substitution to extend
-> Type | Template
-> Type | Target
-> Maybe TCvSubst |

This is similar to `tcMatchTy`, but extends a substitution

tcMatchTysX #

Arguments

:: TCvSubst | Substitution to extend
-> [Type] | Template
-> [Type] | Target
-> Maybe TCvSubst | One-shot substitution

Like `tcMatchTys`, but extending a substitution

tcMatchTyKisX #

Arguments

:: TCvSubst | Substitution to extend
-> [Type] | Template
-> [Type] | Target
-> Maybe TCvSubst | One-shot substitution

Like `tcMatchTyKis`, but extending a substitution

ruleMatchTyKiX #

Arguments

:: TyCoVarSet | template variables
-> RnEnv2 |
-> TvSubstEnv | type substitution to extend
-> Type | Template
-> Type | Target
-> Maybe TvSubstEnv |

This one is called from the expression matcher, which already has a MatchEnv in hand

# Rough matching

roughMatchTcs :: [Type] -> [Maybe Name] #

instanceCantMatch :: [Maybe Name] -> [Maybe Name] -> Bool #

typesCantMatch :: [(Type, Type)] -> Bool #

Given a list of pairs of types, are any two members of a pair surely apart, even after arbitrary type function evaluation and substitution?

tcUnifyTy :: Type -> Type -> Maybe TCvSubst #

Simple unification of two types; all type variables are bindable Precondition: the kinds are already equal

tcUnifyTyKi :: Type -> Type -> Maybe TCvSubst #

Like `tcUnifyTy`, but also unifies the kinds

tcUnifyTys #

Arguments

:: (TyCoVar -> BindFlag) |
-> [Type] |
-> [Type] |
-> Maybe TCvSubst | A regular one-shot (idempotent) substitution that unifies the erased types. See comments for `tcUnifyTysFG`

tcUnifyTyKis :: (TyCoVar -> BindFlag) -> [Type] -> [Type] -> Maybe TCvSubst #

Like `tcUnifyTys` but also unifies the kinds

tcUnifyTysFG :: (TyVar -> BindFlag) -> [Type] -> [Type] -> UnifyResult #

`tcUnifyTysFG bind_tv tys1 tys2` attepts to find a substitution `s` (whose domain elements all respond `BindMe` to `bind_tv`) such that `s(tys1)` and that of `s(tys2)` are equal, as witnessed by the returned Coercions. This version requires that the kinds of the types are the same, if you unify left-to-right.

tcUnifyTyWithTFs #

Arguments

:: Bool | True = do two-way unification; False = do one-way matching. See end of sec 5.2 from the paper
-> Type |
-> Type |
-> Maybe TCvSubst |

Unify two types, treating type family applications as possibly unifying with anything and looking through injective type family applications. Precondition: kinds are the same

data BindFlag #

Constructors

BindMe |
Skolem |

Instances

Eq BindFlag # |
Methods (==) :: BindFlag -> BindFlag -> Bool # (/=) :: BindFlag -> BindFlag -> Bool #

type UnifyResult = UnifyResultM TCvSubst #

data UnifyResultM a #

Constructors

Unifiable a |
MaybeApart a |
SurelyApart |

Instances

Monad UnifyResultM # |
Methods (>>=) :: UnifyResultM a -> (a -> UnifyResultM b) -> UnifyResultM b Source # (>>) :: UnifyResultM a -> UnifyResultM b -> UnifyResultM b Source # return :: a -> UnifyResultM a Source # fail :: String -> UnifyResultM a Source #
Functor UnifyResultM # |
Methods fmap :: (a -> b) -> UnifyResultM a -> UnifyResultM b Source # (<$) :: a -> UnifyResultM b -> UnifyResultM a Source #
Applicative UnifyResultM # |
Methods pure :: a -> UnifyResultM a Source # (<*>) :: UnifyResultM (a -> b) -> UnifyResultM a -> UnifyResultM b Source # liftA2 :: (a -> b -> c) -> UnifyResultM a -> UnifyResultM b -> UnifyResultM c Source # (*>) :: UnifyResultM a -> UnifyResultM b -> UnifyResultM b Source # (<*) :: UnifyResultM a -> UnifyResultM b -> UnifyResultM a Source #
Alternative UnifyResultM # |
Methods empty :: UnifyResultM a Source # (<|>) :: UnifyResultM a -> UnifyResultM a -> UnifyResultM a Source # some :: UnifyResultM a -> UnifyResultM [a] Source # many :: UnifyResultM a -> UnifyResultM [a] Source #
MonadPlus UnifyResultM # |
Methods mzero :: UnifyResultM a Source # mplus :: UnifyResultM a -> UnifyResultM a -> UnifyResultM a Source #
Outputable a => Outputable (UnifyResultM a) # |
Methods ppr :: UnifyResultM a -> SDoc # pprPrec :: Rational -> UnifyResultM a -> SDoc #

liftCoMatch :: TyCoVarSet -> Type -> Coercion -> Maybe LiftingContext #

`liftCoMatch` is sort of inverse to `liftCoSubst`. In particular, if `liftCoMatch vars ty co == Just s`, then `listCoSubst s ty == co`, where `==` there means that the result of `liftCoSubst` has the same type as the original co; but may be different under the hood. 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. Note that this function is incomplete -- it might return Nothing when there does indeed exist a possible lifting context.

This function is incomplete in that it doesn't respect the equality in `eqType`. That is, it's possible that this will succeed for t1 and fail for t2, even when t1 `eqType` t2. That's because it depends on there being a very similar structure between the type and the coercion. This incompleteness shouldn't be all that surprising, especially because it depends on the structure of the coercion, which is a silly thing to do.

The lifting context produced doesn't have to be exacting in the roles of the mappings. This is because any use of the lifting context will also require a desired role. Thus, this algorithm prefers mapping to nominal coercions where it can do so.