[Haskell-beginners] incoherent instance question

David McBride toad3k at gmail.com
Mon Jun 4 12:54:28 UTC 2018


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.

Just remember that they are "typeclasses", not "classclasses".  When you
write

class Foo a where foo :: ...
instance Show a => Foo a where foo = something

Everything seems fine, but then you could write additional classes like this

instance Read a => Foo a where foo = something_else

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.

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.

On Sun, Jun 3, 2018 at 11:42 PM, Graham Gill <math.simplex at gmail.com> wrote:

> Please see the paste: https://pastebin.com/zBim7Zkx
>
> 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.
>
> 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.
>
> 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.
>
> 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?)
>
> In the paste, I have INCOHERENT pragmas only at lines 11 and 17. This
> gives me the following behaviour in ghci:
>
>    1. minBound, maxBound, upperBound and lowerBound instantiated to type
>    Foo all function as expected, evaluating to the appropriate lower or upper
>    bound.
>    2. upperBound and maxBound instantiated at Bar give overlapping
>    instance errors for UpperBounded, as expected.
>    3. lowerBound :: Bar evaluates to C, as expected.
>    4. minBound :: Bar gives an overlapping instance error for
>    UpperBounded:
>
> *UpperLowerBounded> minBound :: Bar
>
> <interactive>:141:1: error:
>    • Overlapping instances for UpperBounded Bar
>        arising from a use of ‘minBound’
>      Matching instances:
>        instance [safe] Bounded a => UpperBounded a
>          -- Defined at UpperLowerBounded.hs:14:10
>        instance [safe] UpperBounded Bar -- Defined at
> UpperLowerBounded.hs:31:10
>    • In the expression: minBound :: Bar
>      In an equation for ‘it’: it = minBound :: Bar
>
>
> It's #4 that I don't understand. An explanation would be very much
> appreciated. (Also, what's a [safe] instance?)
>
> Regards,
> Graham
>
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20180604/92c32b74/attachment.html>


More information about the Beginners mailing list