<div dir="ltr"><div><font face="arial, sans-serif"><br></font></div><font face="arial, sans-serif">Thank you to Richard for the Tweag tutorials on Pattern Synonyms. That third one on Matchers was heavy going. I didn't find an answer (or did I miss it?) to something that's bugging me:</font><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">>    pattern  SmartConstr :: Ord a => () => ...</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">Seems to mean:</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">* Required constraint is Ord a  -- fine, for building</font></div><div><font face="arial, sans-serif">* Provided constraint is Ord a  -- why? for matching/consuming</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">I'm using `SmartConstr` with some logic inside it to validate/build a well-behaved data structure. But this is an ordinary H98 datatype, not a GADT.</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">I don't want to expose the datatype's underlying constructor, because client code could break the abstraction/build an ill-formed data structure.</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">If I pattern-match on `SmartConstr`, the consuming function wants `Ord a`. But I can't always provide `Ord a`, because this isn't a GADT. And the client's function could be doing something that doesn't need `Ord a` -- like counting elements, or showing them or streaming to a List, etc.</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">This feels a lot like one of the things that's wrong with 'stupid theta' datatype contexts.</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">My work-round seems to be to define a second `ReadOnlyConstr` without constraints, that's unidirectional/ can't be used for building.</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">For definiteness, the use case is a underlying non-GADT constructor for a BST</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">>      Node :: Tree a -> a -> Tree a -> Tree a</font></div><div><font face="arial, sans-serif">></font></div><div><font face="arial, sans-serif">>    pattern SmartNode :: Ord a => () => Tree a -> a -> Tree a -> Tree a</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">with the usual semantics that the left Tree holds elements less than this node. Note it's the same `a` with the same `Ord a` 'all the way down' the Tree.</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">If some function is consuming the Tree, it can provide constraints for its own purposes:</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">>    member   :: Ord a => a -> Tree a -> Bool</font></div><div><font face="arial, sans-serif">>    dumbElem :: Eq a  => a -> Tree a -> Bool</font></div><div><font face="arial, sans-serif">>    max      :: Ord a => Tree a -> a</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">(That again is the same thinking behind deprecating datatype contexts.)</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">>    countT (SmartNode l x r) = countT l + 1 + countT r               -- why infer Ord a => ?</font></div><div><font face="arial, sans-serif">></font></div><div><font face="arial, sans-serif">>    class FancyShow t  where</font></div><div><font face="arial, sans-serif">>      fancyShow :: Show a => Int -> t a -> String</font></div><div><font face="arial, sans-serif">>    instance FancyShow Tree  where</font></div><div><font face="arial, sans-serif">>      fancyShow indent (SmartNode l x r) = ...         -- rejected: Could not deduce Ord a</font></div><div><font face="arial, sans-serif">></font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">(Ref the parallel thread on Foldable: client code can't declare an instance for a Constructor class using SmartConstr.)</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">I can see commonly your Provided would be at least the constraints inside the GADT constructor. But why presume I have a GADT?  (And yes I get that a devlishly smart pattern might be building different GADT constrs/various constraints, so this is difficult to infer.)</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">AntC</font></div><div><font face="arial, sans-serif"><br></font></div><div><br></div></div>