public Type eval() { if (reduced != null) return reduced; if (inEval) return this; final Type baseEval = base.deref().eval(); final Type argEval = arg.deref().eval(); if (!(baseEval instanceof TypeCons)) // error has been raised return this; final TypeCons cons = (TypeCons) baseEval; final Type body = cons.getBody(); if (body == null) return reduced(baseEval, argEval); // check base abs param kind against arg kind if (!checkKindAgreement(cons, argEval)) // error has been raised return this; // evaluate by building param->arg subst map and // applying it to body term final SubstMap argMap = new SubstMap(); final Collection<TypeParam> params = body.getParams().values(); if (params.size() == 1) { final TypeParam param = params.iterator().next(); assert param.getTypeScope() == body : "nope"; argMap.put(param, argEval); } else { if (!(argEval instanceof TypeTuple)) assert false; final Iterator<Type> argList = ((TypeTuple) argEval).getMembers().iterator(); for (final TypeParam param : params) { assert param.getTypeScope() == body : "nope"; argMap.put(param, argList.next()); } } final Type bodySubst = new TypeApplier(body, argMap).apply(); // evaluate body with args substituted for params inEval = true; reduced = bodySubst.eval(); inEval = false; if (Session.isDebug()) Session.debug( body.getLoc(), "eval {0}({1}) => {2}", body.dump(), argMap.dump(), reduced.dump()); return reduced; }
public TypeParam(final TypeParam param) { this(param.getLoc(), param.getName(), param.getKind(), param.getConstraint()); }