/** @see jaskell.compiler.JaskellVisitor#visit(Abstraction) */ public Object visit(Abstraction a) { try { Type t = a.getType(); if (t != null) return subst.substitute(t); log.finest("Visiting abstraction : " + a); Expression body = a.getBody(); /* duplicate bindings map to assign types to variables */ pushContext(a.getBindings()); /* create fresh type variables as type for each bound * variable */ Iterator it = namesMap.values().iterator(); LinkedList tl = new LinkedList(); while (it.hasNext()) { LocalBinding name = (LocalBinding) it.next(); Type vt = TypeFactory.freshBinding(); name.setType(vt); tl.add(vt); } Type tv = TypeFactory.freshBinding(); /* create type with all variables for function */ Type ft = Types.fun(tl, tv); log.finer("In abstraction, setting type to " + ft); a.setType(ft); /* analyze body */ Type bt = (Type) body.visit(this); /* unify return type of function with type of body */ Type ret = tu.unify(PrimitiveType.getReturnType(ft), bt, typeVariablesMap); TyvarSubstitution tys = new TyvarSubstitution(typeVariablesMap); tys.visit(a); log.finer("Done abstraction, setting type from " + ft + " to " + a.getType()); popContext(); return a.getType(); } catch (TypeError te) { if (te.getLineCol() == null) te.setLineCol(a.getTag("source")); throw te; } }