<div dir="auto">I meant my own brief attempt. Severing them absolutely wouldn't make them less useful.<div dir="auto"><br></div><div dir="auto">pattern Foo :: ...</div><div dir="auto">pattern Foo x <- ....</div><div dir="auto"><br></div><div dir="auto">constructor Foo :: ...</div><div dir="auto">constructor Foo x = ...</div><div dir="auto"><br></div><div dir="auto">Separate namespaces, so you can have both, and both can be bundled with a type.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Oct 5, 2021, 1:11 PM Edward Kmett <<a href="mailto:ekmett@gmail.com">ekmett@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Oct 5, 2021 at 12:39 PM David Feuer <<a href="mailto:david.feuer@gmail.com" target="_blank" rel="noreferrer">david.feuer@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto">To be clear, the proposal to allow different constraints was accepted, but integrating it into the current, incredibly complex, code was well beyond the limited abilities of the one person who made an attempt. Totally severing pattern synonyms from constructor synonyms (giving them separate namespaces) would be a much simpler design.</div></blockquote><div><br></div><div>It might be simpler in some ways, despite needing yet another syntactic marker, etc. but also would make them a lot less useful for a lot of places where they are used today, e.g. to provide backwards compatibility for old constructors as an API changes, and the like.</div><div><br></div><div>Before I left MIRI, Cale had started work on these for us. Is that the work you are thinking of, or are you thinking of an earlier effort?</div><div><br></div><div>-Edward</div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Oct 5, 2021, 12:33 PM Richard Eisenberg <<a href="mailto:lists@richarde.dev" target="_blank" rel="noreferrer">lists@richarde.dev</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><br><div><br><blockquote type="cite"><div>On Oct 3, 2021, at 5:38 AM, Anthony Clayden <<a href="mailto:anthony.d.clayden@gmail.com" rel="noreferrer noreferrer" target="_blank">anthony.d.clayden@gmail.com</a>> wrote:</div><div><div dir="ltr"><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></div></blockquote><div><br></div><div>Yes.</div><br><blockquote type="cite"><div><div dir="ltr"><div><font face="arial, sans-serif">* Provided constraint is Ord a  -- why? for matching/consuming</font></div></div></div></blockquote><div><br></div><div>No. Your signature specified that there are no provided constraints: that's your ().</div><br><blockquote type="cite"><div><div dir="ltr"><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></div></blockquote><div><br></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><blockquote type="cite"><div dir="ltr"><div><br></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></blockquote><div><br></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></div><div>For example:</div><div><br></div><div></div><blockquote type="cite"><div>checkLT5AndReturn :: (Ord a, Num a) => a -> (Bool, a)</div><div>checkLT5AndReturn x = (x < 5, x)</div><div><br></div><div>pattern LessThan5 :: (Ord a, Num a) => a -> a</div><div>pattern LessThan5 x <- ( checkLT5AndReturn -> (True, x) )</div></blockquote><div><br></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><blockquote type="cite"><div dir="ltr"><div><br></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></blockquote><div><br></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></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></div><div>Does this help?</div><div><br></div><div>Richard</div></div></div>_______________________________________________<br>
Glasgow-haskell-users mailing list<br>
<a href="mailto:Glasgow-haskell-users@haskell.org" rel="noreferrer noreferrer" target="_blank">Glasgow-haskell-users@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users" rel="noreferrer noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users</a><br>
</blockquote></div>
_______________________________________________<br>
Glasgow-haskell-users mailing list<br>
<a href="mailto:Glasgow-haskell-users@haskell.org" target="_blank" rel="noreferrer">Glasgow-haskell-users@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users" rel="noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users</a><br>
</blockquote></div></div>
</blockquote></div>