<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/<wbr>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>______________________________<wbr>_________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">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-<wbr>bin/mailman/listinfo/beginners</a><br>
<br></blockquote></div><br></div>