infer e = case e of
VarExpr _ (VarDef k fs) = (\t->(zero,t)) <$> (lookup k >>= instantiate)
//instantiate is key for the let polymorphism!
+ //TODO: field selectors
Op2Expr _ e1 op e2 =
infer e1 >>= \(s1, t1) ->
let given = t1 ->> tv in
op1Type op >>= \expected ->
lift (unify expected given) >>= \s2 ->
- pure ((compose s1 s2), subst s2 tv)
+ pure (compose s1 s2, subst s2 tv)
+ EmptyListExpr _ = (\tv->(zero,tv)) <$> fresh
+ TupleExpr _ (e1, e2) =
+ infer e1 >>= \(s1, t1) ->
+ infer e2 >>= \(s2, t2) ->
+ pure (compose s1 s2, TupleType (t1,t2))
+
+ FunExpr _ f args fs = //todo: fieldselectors
+ lookup f >>= \expected ->
+ mapM infer args >>= \argTypes
IntExpr _ _ = pure $ (zero, IntType)
BoolExpr _ _ = pure $ (zero, BoolType)