+ti e (NTTerm (App a b)) = do
+ tv <- newVar
+ (s1, t1) <- ti e a
+ (s2, t2) <- ti (Map.map (substituteS s1) e) b
+ s3 <- unify (substituteT s2 t1) (TypeFunction t2 tv)
+ return (s3 `composeSub` s2 `composeSub` s1, substituteT s3 tv)
+ti e (NTTerm (Let x a b)) = do
+ (s1, t1) <- ti e a
+ let t' = generalize (Map.map (substituteS s1) e) t1
+ e' = Map.insert x t' e
+ (s2, t2) <- ti (Map.map (substituteS s1) e') b
+ return (s1 `composeSub` s2, t2)
+
+algW :: TypedTerm -> Either String Type
+algW t = fst . runTI $ do