public SubstMap unify(final Loc loc, final Type other, final TypeEnv env) { if (env.checkVisited(this, other)) return SubstMap.EMPTY; if (other instanceof TypeVar) return SubstMap.bindVar(loc, (TypeVar) other, this); // if our application expression can be evaluated, unify against that. if (isAbsApply()) return eval().unify(loc, other, env); final Type otherEval = other.deref().eval(); if (otherEval instanceof TypeApp) { final TypeApp otherApp = (TypeApp) otherEval; final SubstMap baseSubst = base.unify(loc, otherApp.base, env); if (baseSubst != null) { final SubstMap argSubst = arg.subst(baseSubst).unify(loc, otherApp.arg.subst(baseSubst), env); if (argSubst != null) return baseSubst.compose(loc, argSubst); } } else if (kind.equals(otherEval.getKind())) { // other is not an application expression, but kinds match. // other type classes do opportunistic matching of type apps // implementations of unify. This approach is really ad-hoc, // needs to be rationalized. return otherEval.unify(loc, this, env); } return null; }
public Constraints unify(Type t, List<Equation> es) throws NoType { if (t.getClass().equals(FunType.class)) { FunType f = (FunType) t; Constraints unifiedDom = domain.unify(f.domain, es); return codomain.unify(f.codomain, Assignment.asEquations(unifiedDom.assignments)); } else { return t.unifyVar(this, es); } }
@Override public Substitution unify(Type t) throws TypeError { if (t instanceof TypeVar) { return t.unify(this); } if (t instanceof BoolType) { return Substitution.IDENTITY; } throw new TypeMismatchError(); }
public Return(Expr e) { this.e = e; if (Type.unify(method.getReturnType(), e.getType()) != method.getReturnType()) throw new IllegalArgumentException("type mismatch"); }