<div dir="ltr"><div>Please see the paste: <a href="https://pastebin.com/zBim7Zkx">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>