inferTE :: forall a . (Ord a, FreshPickable a)
      => TEContext a
      -> LambdaTerm a
      -> InferenceState (TEContext a, TypeExpr)
inferTE ctxt term = do (newCtxt, typeVar, eqs) <- equations ctxt term
                       sub <- lift $ unify eqs
                       let inferredType = applySubstitution (TEVar typeVar) sub
                           inferredContext = subsContext sub newCtxt
                       return (inferredContext, inferredType)
  where subsContext :: Substitution -> TEContext a -> TEContext a
        subsContext sub = map subsJudgment
          where subsJudgment (x, t) = (x, applySubstitution t sub)
inferTE :: forall a . (Ord a, FreshPickable a)
      => TEContext a
      -> LambdaTerm a
      -> InferenceState (TEContext a, TypeExpr)
inferTE ctxt term = do (newCtxt, typeVar, eqs) <- equations ctxt term
                       sub <- lift $ unify eqs
                       let inferredType = applySubstitution (TEVar typeVar) sub
                           inferredContext = subsContext sub newCtxt
                       return (inferredContext, inferredType)
  where subsContext :: Substitution -> TEContext a -> TEContext a
        subsContext sub = map subsJudgment
          where subsJudgment (x, t) = (x, applySubstitution t sub)
inferTE ctxt term = do (newCtxt, typeVar, eqs) <- equations ctxt term
                       sub <- lift $ unify eqs
                       let inferredType = applySubstitution (TEVar typeVar) sub
                           inferredContext = subsContext sub newCtxt
                       return (inferredContext, inferredType)
  where subsContext :: Substitution -> TEContext a -> TEContext a
        subsContext sub = map subsJudgment
          where subsJudgment (x, t) = (x, applySubstitution t sub)