+tcImprove :: LIE -> TcM s ()
+-- Do unifications based on functional dependencies in the LIE
+tcImprove lie
+ = tcGetInstEnv `thenNF_Tc` \ inst_env ->
+ let
+ nfdss, clas_nfdss, inst_nfdss, ip_nfdss :: [(TcTyVarSet, Name, [FunDep TcType])]
+ nfdss = ip_nfdss ++ clas_nfdss ++ inst_nfdss
+
+ cfdss :: [(Class, [FunDep TcType])]
+ cfdss = getFunDepsOfLIE lie
+ clas_nfdss = [(emptyVarSet, className c, fds) | (c,fds) <- cfdss]
+
+ classes = nub (map fst cfdss)
+ inst_nfdss = [ (free, className c, instantiateFdClassTys c ts)
+ | c <- classes,
+ (free, ts, i) <- classInstEnv inst_env c
+ ]
+
+ ip_nfdss = [(emptyVarSet, n, [([], [ty])]) | (n,ty) <- getIPsOfLIE lie]
+
+ {- Example: we have
+ class C a b c | a->b where ...
+ instance C Int Bool c
+
+ Given the LIE FD C (Int->t)
+ we get clas_nfdss = [({}, C, [Int->t, t->Int])
+ inst_nfdss = [({c}, C, [Int->Bool, Bool->Int])]
+
+ Another way would be to flatten a bit
+ we get clas_nfdss = [({}, C, Int->t), ({}, C, t->Int)]
+ inst_nfdss = [({c}, C, Int->Bool), ({c}, C, Bool->Int)]
+
+ iterImprove then matches up the C and Int, and unifies t <-> Bool
+ -}
+
+ in
+ iterImprove nfdss
+
+
+iterImprove :: [(VarSet, Name, [FunDep TcType])] -> TcM s ()