<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Oct 3, 2021, at 5:38 AM, Anthony Clayden <<a href="mailto:anthony.d.clayden@gmail.com" class="">anthony.d.clayden@gmail.com</a>> wrote:</div><div class=""><div dir="ltr" class=""><div class=""><font face="arial, sans-serif" class=""><br class=""></font></div><div class=""><font face="arial, sans-serif" class="">>    pattern  SmartConstr :: Ord a => () => ...</font></div><div class=""><font face="arial, sans-serif" class=""><br class=""></font></div><div class=""><font face="arial, sans-serif" class="">Seems to mean:</font></div><div class=""><font face="arial, sans-serif" class=""><br class=""></font></div><div class=""><font face="arial, sans-serif" class="">* Required constraint is Ord a  -- fine, for building</font></div></div></div></blockquote><div><br class=""></div><div>Yes.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><font face="arial, sans-serif" class="">* Provided constraint is Ord a  -- why? for matching/consuming</font></div></div></div></blockquote><div><br class=""></div><div>No. Your signature specified that there are no provided constraints: that's your ().</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><font face="arial, sans-serif" class=""><br class=""></font></div><div class=""><font face="arial, sans-serif" class="">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></div></blockquote><div><br class=""></div><div>I believe there is no way to have provided constraints in Haskell98. You would need either GADTs or higher-rank types.</div><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class=""><font face="arial, sans-serif" class="">This feels a lot like one of the things that's wrong with 'stupid theta' datatype contexts.</font></div></div></blockquote><div><br class=""></div><div>You're onto something here. Required constraints are very much like the stupid theta datatype contexts. But, unlike the stupid thetas, required constraints are sometimes useful: they might be needed in order to, say, call a function in a view pattern.</div><div><br class=""></div><div>For example:</div><div><br class=""></div><div></div><blockquote type="cite" class=""><div>checkLT5AndReturn :: (Ord a, Num a) => a -> (Bool, a)</div><div>checkLT5AndReturn x = (x < 5, x)</div><div><br class=""></div><div>pattern LessThan5 :: (Ord a, Num a) => a -> a</div><div>pattern LessThan5 x <- ( checkLT5AndReturn -> (True, x) )</div></blockquote><div><br class=""></div><div>My view pattern requires (Ord a, Num a), and so I must declare these as required constraints in the pattern synonym type. Because vanilla data constructors never do computation, any required constraints for data constructors are always useless.</div><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class=""><font face="arial, sans-serif" class="">For definiteness, the use case is a underlying non-GADT constructor for a BST</font></div><div class=""><font face="arial, sans-serif" class=""><br class=""></font></div><div class=""><font face="arial, sans-serif" class="">>      Node :: Tree a -> a -> Tree a -> Tree a</font></div><div class=""><font face="arial, sans-serif" class="">></font></div><div class=""><font face="arial, sans-serif" class="">>    pattern SmartNode :: Ord a => () => Tree a -> a -> Tree a -> Tree a</font></div><div class=""><font face="arial, sans-serif" class=""><br class=""></font></div><div class=""><font face="arial, sans-serif" class="">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></blockquote><div><br class=""></div><div>Does SmartNode need Ord a to match? Or just to produce a node? It seems that Ord a is used only for production, not for matching. This suggests that you want a separate smartNode function (not a pattern synonym) and to have no constraints on the pattern synonym, which can be unidirectional (that is, work only as a pattern, not as an expression).</div><div><br class=""></div><div>It has been mooted to allow pattern synonyms to have two types: one when used as a pattern and a different one when used as an expression. That might work for you here: you want SmartNode to have no constraints as a pattern, but an Ord a constraint as an expression. At the time, the design with two types was considered too complicated and abandoned.</div><div><br class=""></div><div>Does this help?</div><div><br class=""></div><div>Richard</div></div></body></html>