-//typeExpr (FunExpr p FunCall) = undef
-//typeExpr (VarExpr Pos VarDef) = undef //when checking var-expr, be sure to
- //put the infered type in the context
+typeExpr (FunExpr p (FunCall f es)) = gets (\(st, r)->'Map'.get f st)
+ >>= \mt-> case mt of
+ Nothing = let t = IdType f in putIdent f t >>| pure t
+ Just t = unifyApp t es
+typeExpr (VarExpr p (VarDef ident fs)) = gets (\(st, r)->'Map'.get ident st)
+ >>= \mt->case mt of
+ Nothing = liftT $ Left $ UndeclaredVariableError p ident
+ Just t = unify t fs
+
+unifyApp :: Type [Expr] -> Env Type
+unifyApp t [] = pure t //whoop whoop, functions can return functions
+unifyApp (tf1 ->> tf2) [t1:ts] = (->>) <$> unify tf1 t1 <*> (unifyApp tf2 ts)
+unifyApp t1 t2 = liftT $ Left $ UnifyError zero t1 (IdType "[expressions, FIXME")