Note [Solving tuple constraints]
I tried treating tuple constraints, such as (% Eq a, Show a %), rather like equality-class constraints (see Note [Solving equality classes]). That is, by eagerly decomposing tuple-constraints into their component (Eq a) and (Show a). But discarding the tuple Given (which "replacing" does) means that we may have to reconstruct it for a recursive call. For example f :: (% Eq a, Show a %) => blah f x = ....(f x').... If we decomposed eagerly we'd get f = \(d : (% Eq a, Show a %)). let de = fst d ds = snd d in ....(f (% de, ds %))... and the optimiser may not be clever enough to transform (f (% de, ds %)) into (f d). See #10359 and its test case, and #23398. (This issue is less pressing for equality classes because they have to be unpacked strictly, so CSE-ing away the reconstruction works fine. So at the moment we don't decompose tuple constraints eagerly; instead we mostly just treat them like other constraints. * Given tuples are decomposed via their superclasses, in `canDictCt`. So [G] (% Eq a, Show a %) has superclasses [G] Eq a, [G] Show a * Wanted tuples are decomposed via a built-in "instance". See `GHC.Tc.Instance.Class.matchCTuple` There is a bit of special treatment: search for isCTupleClass.
References 1
- Solving equality classes GHC.Tc.Solver.Dict
Referenced by 2
- GHC.Tc.Solver.Dict call site ×2