Example #1
0
  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;
  }
Example #2
0
  /** internal reality checks on param/arg kinds */
  private boolean checkKindAgreement(final Type abs, final Type argDeref) {
    final Kind absKind = abs.getKind();

    if (!(absKind instanceof ArrowKind)) {
      Session.error(
          loc,
          "internal error: abs {0} has non-lambda kind {1} in type app {2}",
          abs.dump(),
          absKind.dump(),
          dump());

      return false;
    }

    final Kind paramKind = ((ArrowKind) absKind).getParamKind();
    final Kind argKind = argDeref.getKind();

    if (!paramKind.equals(argKind)) {
      Session.error(
          loc,
          "internal error: param kind {0} incompatible with arg kind {1} in type app {2}",
          paramKind.dump(),
          argKind.dump(),
          dump());

      return false;
    }

    return true;
  }
Example #3
0
  @Override
  public boolean equals(final Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    if (!super.equals(o)) return false;

    final TypeParam typeParam = (TypeParam) o;

    if (kind != null ? !kind.equals(typeParam.kind) : typeParam.kind != null) return false;

    if (typeScope != null ? typeScope != typeParam.typeScope : typeParam.typeScope != null)
      return false;

    return true;
  }
Example #4
0
 @Override
 public int hashCode() {
   int result = super.hashCode();
   result = 31 * result + (kind != null ? kind.hashCode() : 0);
   return result;
 }