+Note [Coverage condition]
+~~~~~~~~~~~~~~~~~~~~~~~~~
+For the coverage condition, we used to require only that
+ fv(t2) `subset` oclose(fv(t1), theta)
+
+Example:
+ class Mul a b c | a b -> c where
+ (.*.) :: a -> b -> c
+
+ instance Mul Int Int Int where (.*.) = (*)
+ instance Mul Int Float Float where x .*. y = fromIntegral x * y
+ instance Mul a b c => Mul a [b] [c] where x .*. v = map (x.*.) v
+
+In the third instance, it's not the case that fv([c]) `subset` fv(a,[b]).
+But it is the case that fv([c]) `subset` oclose( theta, fv(a,[b]) )
+
+But it is a mistake to accept the instance because then this defn:
+ f = \ b x y -> if b then x .*. [y] else y
+makes instance inference go into a loop, because it requires the constraint
+ Mul a [b] b
+
+
+%************************************************************************
+%* *
+ Check that a new instance decl is OK wrt fundeps
+%* *
+%************************************************************************
+
+Here is the bad case:
+ class C a b | a->b where ...
+ instance C Int Bool where ...
+ instance C Int Char where ...
+
+The point is that a->b, so Int in the first parameter must uniquely
+determine the second. In general, given the same class decl, and given
+
+ instance C s1 s2 where ...
+ instance C t1 t2 where ...
+
+Then the criterion is: if U=unify(s1,t1) then U(s2) = U(t2).
+
+Matters are a little more complicated if there are free variables in
+the s2/t2.
+
+ class D a b c | a -> b
+ instance D a b => D [(a,a)] [b] Int
+ instance D a b => D [a] [b] Bool
+
+The instance decls don't overlap, because the third parameter keeps
+them separate. But we want to make sure that given any constraint
+ D s1 s2 s3
+if s1 matches
+
+
+\begin{code}
+checkFunDeps :: (InstEnv, InstEnv) -> Instance
+ -> Maybe [Instance] -- Nothing <=> ok
+ -- Just dfs <=> conflict with dfs
+-- Check wheher adding DFunId would break functional-dependency constraints
+-- Used only for instance decls defined in the module being compiled
+checkFunDeps inst_envs ispec
+ | null bad_fundeps = Nothing
+ | otherwise = Just bad_fundeps
+ where
+ (ins_tvs, _, clas, ins_tys) = instanceHead ispec
+ ins_tv_set = mkVarSet ins_tvs
+ cls_inst_env = classInstances inst_envs clas
+ bad_fundeps = badFunDeps cls_inst_env clas ins_tv_set ins_tys
+
+badFunDeps :: [Instance] -> Class
+ -> TyVarSet -> [Type] -- Proposed new instance type
+ -> [Instance]
+badFunDeps cls_insts clas ins_tv_set ins_tys
+ = [ ispec | fd <- fds, -- fds is often empty
+ let trimmed_tcs = trimRoughMatchTcs clas_tvs fd rough_tcs,
+ ispec@(Instance { is_tcs = mb_tcs, is_tvs = tvs,
+ is_tys = tys }) <- cls_insts,
+ -- Filter out ones that can't possibly match,
+ -- based on the head of the fundep
+ not (instanceCantMatch trimmed_tcs mb_tcs),
+ notNull (checkClsFD (tvs `unionVarSet` ins_tv_set)
+ fd clas_tvs tys ins_tys)
+ ]
+ where
+ (clas_tvs, fds) = classTvsFds clas
+ rough_tcs = roughMatchTcs ins_tys
+
+trimRoughMatchTcs :: [TyVar] -> FunDep TyVar -> [Maybe Name] -> [Maybe Name]
+-- Computing rough_tcs for a particular fundep
+-- class C a b c | a c -> b where ...
+-- For each instance .... => C ta tb tc
+-- we want to match only on the types ta, tb; so our
+-- rough-match thing must similarly be filtered.
+-- Hence, we Nothing-ise the tb type right here
+trimRoughMatchTcs clas_tvs (ltvs,_) mb_tcs
+ = zipWith select clas_tvs mb_tcs
+ where
+ select clas_tv mb_tc | clas_tv `elem` ltvs = mb_tc
+ | otherwise = Nothing
+\end{code}
+
+