// = infer env e1
// >>= \(s1, t1)->infer ('Data.Map'.put x (generalize (apply s1 env) t1) env) e2
// >>= \(s2, t2)->pure (s1 oo s2, t2)
-infer env (Let [(x, e1)] e2)
- = fresh
- >>= \tv-> let env` = 'Data.Map'.put x (Forall [] tv) env
- in infer env` e1
- >>= \(s1,t1)-> infer ('Data.Map'.put x (generalize (apply s1 env`) t1) env`) e2
- >>= \(s2, t2)->pure (s1 oo s2, t2)
+//infer env (Let [(x, e1)] e2)
+// = fresh
+// >>= \tv-> let env` = 'Data.Map'.put x (Forall [] tv) env
+// in infer env` e1
+// >>= \(s1,t1)-> unify t1 tv
+// >>= \t->infer ('Data.Map'.put x (generalize (apply s1 env`) t1) env`) e2
+// >>= \(s2, t2)->pure (s1 oo s2, t2)
+infer env (Let xs e2)
+ # (ns, bs) = unzip xs
+ = sequence [fresh\\_<-ns]
+ >>= \tvs-> let env` = foldr (uncurry putenv) env (zip2 ns tvs)
+ in unzip <$> sequence (map infer env`) bs
+ >>= \(ss,ts)-> unify t1 tv
+// >>= \t->infer ('Data.Map'.put x (generalize (apply s1 env`) t1) env`) e2
+// >>= \(s2, t2)->pure (s1 oo s2, t2)
+where
+ putenv :: [Char] -> (Type TypeEnv -> TypeEnv)
+ putenv k = 'Data.Map'.put k o Forall []