<div dir="ltr">I must be slow on the uptake. I've just grokked this equivalence -- or is it? Consider<div><br></div><div>>    data Eq a => Set a = NilSet | ConsSet a (Set a)     -- from the Language report</div><div>></div><div>>    -- ConsSet :: forall a. Eq a => a -> Set a => Set a   -- inferred/per report</div><div>></div><div>>    <span style="font-family:Arial,Helvetica,sans-serif">--  equiv with Pattern syn 'Required' constraint</span></div>>    data Set' a = NilSet' | ConsSet' a (Set' a)     -- no DT context<br>><div>>    pattern ConsSetP :: (Eq a) => () => a -> (Set' a) -> (Set' a)<br>>    pattern ConsSetP x xs = ConsSet' x xs<br>><br><div>>    ffP ((ConsSet x xs), (ConsSetP y ys)) = (x, y)<br></div></div><div>></div><div>>    -- ffP :: forall {a} {b}. (Eq a, Eq b) => (Set a, Set' b) -> (a, b)   -- inferred</div><div><br></div><div>The signature decl for `ConsSetP` explicitly gives both the Required `(Eq a) =>` and Provided `() =>` constraints, but the Provided could be omitted, because it's empty. I get the same signature for both `ConsSetP` as `ConsSet` with the DT Context. Or is there some subtle difference?</div><div><br></div><div>This typing effect is what got DT Contexts called 'stupid theta' and deprecated/removed from the language standard. ("widely considered a mis-feature", as GHC is keen to tell me.) If there's no difference, why re-introduce the feature for Patterns? That is, why go to the bother of the double-context business, which looks weird, and behaves counter to usual signatures:</div><div><br></div><div>>    foo :: (Eq a) => (Show a) => a -> a</div><div>>    --   foo :: forall {a}. (Eq a, Show a) => a -> a     -- inferred</div><div><br></div><div>There is a slight difference possible with Pattern synonyms, compare:</div><div><br></div><div>>    pattern <span style="font-family:Arial,Helvetica,sans-serif">NilSetP :: (Eq a) => () => (Set' a)</span></div>>    pattern NilSetP = NilSet'<div>></div><div>>    -- NilSetP :: forall {a}. Eq a => Set' a             -- inferred</div><div>>    -- NilSet   :: forall {a}.      => Set a                   -- inferred/per report</div><div><br></div><div>Using `NilSetP` somewhere needs giving an explicit signature/otherwise your types are ambiguous; but arguably that's a better discipline than using `NilSet` and allowing a Set with non-comparable element types.</div><div><br></div><div>AntC</div></div>