+Note [Adding superclasses]
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+Since dictionaries are canonicalized only once in their lifetime, the
+place to add their superclasses is canonicalisation (The alternative
+would be to do it during constraint solving, but we'd have to be
+extremely careful to not repeatedly introduced the same superclass in
+our worklist). Here is what we do:
+
+For Givens:
+ We add all their superclasses as Givens.
+
+For Wanteds:
+ Generally speaking we want to be able to add superclasses of
+ wanteds for two reasons:
+
+ (1) Oportunities for improvement. Example:
+ class (a ~ b) => C a b
+ Wanted constraint is: C alpha beta
+ We'd like to simply have C alpha alpha. Similar
+ situations arise in relation to functional dependencies.
+
+ (2) To have minimal constraints to quantify over:
+ For instance, if our wanted constraint is (Eq a, Ord a)
+ we'd only like to quantify over Ord a.
+
+ To deal with (1) above we only add the superclasses of wanteds
+ which may lead to improvement, that is: equality superclasses or
+ superclasses with functional dependencies.
+
+ We deal with (2) completely independently in TcSimplify. See
+ Note [Minimize by SuperClasses] in TcSimplify.
+
+
+ Moreover, in all cases the extra improvement constraints are
+ Derived. Derived constraints have an identity (for now), but
+ we don't do anything with their evidence. For instance they
+ are never used to rewrite other constraints.
+
+ See also [New Wanted Superclass Work] in TcInteract.
+
+
+For Deriveds:
+ We do nothing.
+
+Here's an example that demonstrates why we chose to NOT add
+superclasses during simplification: [Comes from ticket #4497]
+
+ class Num (RealOf t) => Normed t
+ type family RealOf x
+
+Assume the generated wanted constraint is:
+ RealOf e ~ e, Normed e
+If we were to be adding the superclasses during simplification we'd get:
+ Num uf, Normed e, RealOf e ~ e, RealOf e ~ uf
+==>
+ e ~ uf, Num uf, Normed e, RealOf e ~ e
+==> [Spontaneous solve]
+ Num uf, Normed uf, RealOf uf ~ uf
+
+While looks exactly like our original constraint. If we add the superclass again we'd loop.
+By adding superclasses definitely only once, during canonicalisation, this situation can't
+happen.
+
+\begin{code}
+
+newSCWorkFromFlavored :: EvVar -> CtFlavor -> Class -> [Xi] -> TcS WorkList
+-- Returns superclasses, see Note [Adding superclasses]
+newSCWorkFromFlavored ev orig_flavor cls xis
+ | isDerived orig_flavor
+ = return emptyWorkList -- Deriveds don't yield more superclasses because we will
+ -- add them transitively in the case of wanteds.
+
+ | Just gk <- isGiven_maybe orig_flavor
+ = case gk of
+ GivenOrig -> do { let sc_theta = immSuperClasses cls xis
+ flavor = orig_flavor
+ ; sc_vars <- mapM newEvVar sc_theta
+ ; _ <- zipWithM_ setEvBind sc_vars [EvSuperClass ev n | n <- [0..]]
+ ; mkCanonicals flavor sc_vars }
+ GivenSolved -> return emptyWorkList
+ -- Seems very dangerous to add the superclasses for dictionaries that may be
+ -- partially solved because we may end up with evidence loops.
+
+ | isEmptyVarSet (tyVarsOfTypes xis)
+ = return emptyWorkList -- Wanteds with no variables yield no deriveds.
+ -- See Note [Improvement from Ground Wanteds]
+
+ | otherwise -- Wanted case, just add those SC that can lead to improvement.
+ = do { let sc_rec_theta = transSuperClasses cls xis
+ impr_theta = filter is_improvement_pty sc_rec_theta
+ Wanted wloc = orig_flavor
+ ; der_ids <- mapM newDerivedId impr_theta
+ ; mkCanonicals (Derived wloc) der_ids }
+
+
+is_improvement_pty :: PredType -> Bool
+-- Either it's an equality, or has some functional dependency
+is_improvement_pty (EqPred {}) = True
+is_improvement_pty (ClassP cls _ty) = not $ null fundeps
+ where (_,fundeps,_,_,_,_) = classExtraBigSig cls
+is_improvement_pty _ = False
+
+
+
+
+canIPToWorkList :: CtFlavor -> EvVar -> IPName Name -> TcType -> TcS WorkList
+-- See Note [Canonical implicit parameter constraints] to see why we don't
+-- immediately canonicalize (flatten) IP constraints.
+canIPToWorkList fl v nm ty
+ = return $ workListFromNonEq (CIPCan { cc_id = v
+ , cc_flavor = fl
+ , cc_ip_nm = nm
+ , cc_ip_ty = ty })