<div dir="ltr"><span style="text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">Thanks for the explanation David. The problem is clear from your description, and when you *really* do want to do it anyway I guess that's what the INCOHERENT and OVERLAPS/OVERLAPPING pragmas are for, to help you control the types.</span><br><div><span style="text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><br></span></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span style="text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">Just remember that they are "typeclasses", not "classclasses".</span></span></blockquote><div><br></div><div>Actually I wasn't thinking in terms of "classclasses", instead, of mathematical equivalences. A set of reals is bounded iff it is both upper and lower bounded. I wanted to try to express that in types, and wondered if I could do it without resorting to asymmetrical syntax (the newtype suggestion).</div><div><br></div><div>Regards,</div><div>Graham</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Jun 4, 2018 at 8:54 AM David McBride <<a href="mailto:toad3k@gmail.com">toad3k@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>This is a common thing that people try to do.  I want class A to apply to any type in which class B already applies.  It seems to mimic what would work in object oriented programming and it is hard to see at first why it doesn't work in haskell.</div><div><br></div><div>Just remember that they are "typeclasses", not "classclasses".  When you write</div><div><br></div><div>class Foo a where foo :: ...<br></div><div>instance Show a => Foo a where foo = something<br></div><div><br></div><div>Everything seems fine, but then you could write additional classes like this</div><div><br></div><div>instance Read a => Foo a where foo = something_else<br></div><div><br></div><div>And what if you had a type that is both a Read and Show, like Int?  Now there are two different things it could do -- something and something_else.  How to decide?  Based on order?  But then the behavior of the program could dramatically change based on the import order.<br></div><div><br></div><div>I would advise you to treat Bounded, UpperBounded, and LowerBounded to be separate properties and define them on all types explicitly rather than trying to obtain instances for free.<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jun 3, 2018 at 11:42 PM, Graham Gill <span dir="ltr"><<a href="mailto:math.simplex@gmail.com" target="_blank">math.simplex@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Please see the paste: <a href="https://pastebin.com/zBim7Zkx" target="_blank">https://pastebin.com/zBim7Zkx</a></div><div><br></div>I'm experimenting with defining UpperBounded and LowerBounded typeclasses. An example type belonging to the latter that is not also Bounded would be type Natural from Numeric.Natural.<div><br></div><div>I want to say that if a type is Bounded, then it is also UpperBounded and LowerBounded. If a type is both UpperBounded and LowerBounded, then it is also Bounded.</div><div><br></div><div>To express the constraints, I need FlexibleInstances and UndecidableInstances extensions. These allow the module to load into ghci (8.4.2) with only a warning, but, without the INCOHERENT pragmas, I get an overlapping instance error if I try to evaluate minBound, maxBound, upperBound or lowerBound instantiated to either of the types Foo or Bar.</div><div><br></div><div>A solution is to apply the INCOHERENT pragma to the instances at lines 11, 14 and 17. Reading over section 10.8.3.6. Overlapping instances in the GHC User Guide, I believe I understand. (Is there a better solution?)</div><div><br></div><div>In the paste, I have INCOHERENT pragmas only at lines 11 and 17. This gives me the following behaviour in ghci:</div><div><ol><li>minBound, maxBound, upperBound and lowerBound instantiated to type Foo all function as expected, evaluating to the appropriate lower or upper bound.<br></li><li>upperBound and maxBound instantiated at Bar give overlapping instance errors for UpperBounded, as expected.</li><li>lowerBound :: Bar evaluates to C, as expected.</li><li>minBound :: Bar gives an overlapping instance error for UpperBounded:</li></ol><div><span style="font-family:monospace"><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">*UpperLowerBounded> minBound :: Bar
</span><br>
<br><span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)"><interactive>:141:1: </span><span style="font-weight:bold;color:rgb(255,84,84);background-color:rgb(255,255,255)">error:</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
</span><br><span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">    • Overlapping instances for UpperBounded Bar</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
</span><br><span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">        arising from a use of ‘minBound’</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
</span><br><span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">      Matching instances:</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
</span><br><span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">        instance [safe] Bounded a => UpperBounded a</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
</span><br><span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">          -- Defined at UpperLowerBounded.hs:14:10</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
</span><br><span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">        instance [safe] UpperBounded Bar -- Defined at UpperLowerBounded.hs:31:10</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
</span><br><span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">    • In the expression: minBound :: Bar</span><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
</span><br><span style="font-weight:bold;color:rgb(0,0,0);background-color:rgb(255,255,255)">      In an equation for ‘it’: it = minBound :: Bar</span><br><span style="color:rgb(0,0,0);background-color:rgb(255,255,255)">
</span><br></span><br></div></div><div>It's #4 that I don't understand. An explanation would be very much appreciated. (Also, what's a [safe] instance?)</div><div><br></div><div>Regards,</div><div>Graham</div><div><br></div></div>
<br>_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
<br></blockquote></div><br></div>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
</blockquote></div>