<div dir="ltr"><div>[Picking up a cafe thread from February that fits here <a href="https://mail.haskell.org/pipermail/haskell-cafe/2021-February/133459.html">https://mail.haskell.org/pipermail/haskell-cafe/2021-February/133459.html</a>.]</div><div><br></div><pre style="white-space:pre-wrap;color:rgb(0,0,0)">Am 23.02.21 um 20:07 schrieb Richard Eisenberg:
><i> You might be interested in my recent paper on exactly this problem:
</i>><i> how to make DatatypeContexts actually work the way you want:
</i>><i> <a href="https://richarde.dev/papers/2020/partialdata/partialdata.pdf">https://richarde.dev/papers/2020/partialdata/partialdata.pdf</a>
</i>><i> <<a href="https://richarde.dev/papers/2020/partialdata/partialdata.pdf">https://richarde.dev/papers/2020/partialdata/partialdata.pdf</a>>.</i></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font size="2"><br></font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font size="2">I think that paper is _not_ how DatatypeContexts should work -- at least for the example in that thread of `fmap` over a data structure wanting to preserve some invariant, such as unique elements.</font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><ul><li><font size="2">For the matching/Provided constraints the paper at least does no harm by magically unveiling constraints via a Well-Formed-Type mechanism. It would equally do no harm by just not Providing any constraints at all.</font></li><li><font size="2">For the building/Required constraints: it would do harm to magically unveil (for example) a computation to squish out duplicates or re-order elements by their `fmap`ed result.</font></li></ul></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font size="2">The Laws for `Functor.fmap` include "</font>preserving the structure of<span style="background-color:rgb(254,254,254);color:rgb(17,17,17);font-family:"PT Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Cantarell,"Helvetica Neue",sans-serif;font-size:14px;letter-spacing:0.024px"> " the Functor. Squishing out duplicates/reordering/rebalancing breaks that.</span></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font size="2" style="background-color:rgb(255,255,255)"><span style="color:rgb(17,17,17);font-family:"PT Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Cantarell,"Helvetica Neue",sans-serif;letter-spacing:0.024px">I</span><font face="monospace"><span style="color:rgb(17,17,17);letter-spacing:0.024px">nstead of `fmap` you should use `Foldable.foldMap :: </span><a href="https://hackage.haskell.org/package/base-4.16.0.0/docs/Data-Monoid.html#t:Monoid" title="Data.Monoid" style="margin:0px;padding:0px;text-decoration-line:none;color:rgb(158,53,143);letter-spacing:0.024px">Monoid</a><span style="color:rgb(17,17,17);letter-spacing:0.024px"> m => (a -> m) -> t a -> m`; with `m` instance of the form `Ord b => Monoid (t b)` -- `Ord` induced from the Datatype context of `t`. Then there is a mechanism to pass in the `Ord` dictionary from outside/no need for WFT magic.</span></font></font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><span style="color:rgb(17,17,17);letter-spacing:0.024px;background-color:rgb(255,255,255)"><font face="monospace" size="2">I get it that Required `Ord b` is a poor stand-in for the invariant: no duplicates; elements in ascending sequence; BST balanced. So the Monoid instance still couldn't expose the underlying data constructors.</font></span></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><span style="color:rgb(17,17,17);letter-spacing:0.024px;background-color:rgb(255,255,255)"><font face="monospace" style="" size="2">Forcing to use `foldMap` at least puts it in the programmer's face that trying to use `fmap` is a type error standing in for law-breaking.</font></span></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><span style="color:rgb(17,17,17);font-family:monospace;font-size:14px;letter-spacing:0.024px;background-color:rgb(255,255,255)">AntC</span></pre><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 7 Jan 2022 at 15:00, Anthony Clayden <<a href="mailto:anthony.d.clayden@gmail.com">anthony.d.clayden@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="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 7 Jan 2022 at 09:08, Richard Eisenberg <<a href="mailto:lists@richarde.dev" target="_blank">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 Jan 5, 2022, at 9:19 PM, Anthony Clayden <<a href="mailto:anthony.d.clayden@gmail.com" target="_blank">anthony.d.clayden@gmail.com</a>> wrote:</div><br><div><div style="font-family:Helvetica;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none"><font face="monospace">So Pattern syns seem to be giving exactly the 'stupid theta' behaviour.</font></div></div></blockquote><div><br></div><div>In your example, yes: the Required context is "stupid" in the way that "stupid theta" is. The reason to have a Required context is if your pattern synonym does computation that requires a constraint. ...</div></div></div></blockquote><div><br></div><div>I don't think that's the only (or even the chief) reason. Wadler's response on that 1999 thread is telling</div><div><br></div><div>"<span style="color:rgb(0,0,0);font-family:monospace,monospace;font-size:1em">Often, a type will make no sense without the </span><span style="color:rgb(0,0,0);font-family:monospace,monospace;font-size:1em">constraints; e.g., an association list type Alist a b makes no sense </span><span style="color:rgb(0,0,0);font-family:monospace,monospace;font-size:1em">unless Eq a holds.  The class constraints on data declarations were a </span><span style="color:rgb(0,0,0);font-family:monospace,monospace;font-size:1em">simple way for the user to ask the compiler to enforce this invariant. </span><span style="color:rgb(0,0,0);font-family:monospace,monospace;font-size:1em">They have compile-time effect only, no effect whatsoever on run-time </span><span style="font-size:1em;color:rgb(0,0,0);font-family:monospace,monospace">(in particular, no dictionaries should be passed).</span>  "</div><div><br></div><div><br></div></div></div>
</blockquote></div></div>