   visitExpressions ast, (expression) ->
     expressions.push "#{collapse toHtml expression} :: #{highlightType expression.tea}" if expression.tea
   types: values mapMap (__ highlightType, _type), subtractMaps ctx._scope(), builtInDefinitions()
-  subs: subToObject mapSub highlightType, ctx.substitution
+  subs: printSubstitution ctx.substitution
   fails: ctx.substitution.fails
   ast: expressions
   deferred: ctx.deferredBindings()
+
+printSubstitution = (sub) ->
+  subToObject mapSub highlightType, sub
 
 mapTypingBare = (fn, string) ->
   ast = astize tokenize string

  vars = subtractSets (findFree type), ctx.allBoundTypeVariables()
  quantify vars, type

# Takes a set of fixed type variables, a set of type variables which
# should be quantified and a list of constraints
# returns deferred and retained constraints
deferConstraints = (ctx, fixedVars, quantifiedVars, constraints) ->
  reducedConstraints = reduceConstraints ctx, constraints
  throw new Error "could not reduce constraints in deferConstraints" unless reducedConstraints
  isFixed = (constraint) ->
    # log fixedVars, constraint, (findFree constraint)
    isSubset fixedVars, (findFree constraint)
  [deferred, retained] = partition isFixed, reducedConstraints
  # TODO: handle ambiguity when reducedConstraints include variables not in
  # fixedVars or quantifiedVars

irDefinitionTranslate = (ctx, {type, expression}) ->
  finalType = substitute ctx.substitution, type
  reducedConstraints = reduceConstraints ctx, finalType.constraints
  ctx.updateClassParams()
  # TODO: what about the class dictionaries order?
  counter = {}
  classParams = newMap()
