     else if type.TypeApp
       isNormalizedConstraintArgument type.op
 
-
 includesJsType = (type) ->
-  if type.TypeConstr
+  if type.TypeVariable and type.ref.val
+    includesJsType type.ref.val
+  else if type.TypeConstr
     typeEq type, jsType
   else if type.TypeApp
     (includesJsType type.op) or (includesJsType type.arg)
 
 typeEq = (a, b) ->
-  if a.TypeVariable and b.TypeVariable or
-      a.TypeConstr and b.TypeConstr
+  if a.TypeVariable and b.TypeVariable and a.name is b.name
+    yes
+  else if a.TypeVariable and a.ref.val
+    typeEq a.ref.val, b
+  else if b.TypeVariable and b.ref.val
+    typeEq a, b.ref.val
+  else if a.TypeConstr and b.TypeConstr
     a.name is b.name
   else if a.QuantifiedVar and b.QuantifiedVar
     a.var is b.var

unifyFail = (t1, t2) ->
  typeFail "Types don't match: ", t1, t2

bindVariable = (variable, type) ->
  if type.TypeVariable and variable.name is type.name
    emptySubstitution()
  else if inSet (findFree type), variable.name

#       is not a function then it can't need type class dictionaries
#       ^.___ not necessarily, we could have a tuple of functions or similar
irDefinitionTranslate = (ctx, {type, expression, reference, bare}) ->
  finalType = type#substitute ctx.substitution, type
  allConstraints = (addConstraintsFrom ctx,
    {type, name: reference?.name, scopeIndex: reference?.scopeIndex}, finalType).constraints
  reducedConstraints =
