[Haskell-cafe] class question

Stefan O'Rear stefanor at cox.net
Sun Jan 21 14:20:36 EST 2007


On Sun, Jan 21, 2007 at 08:00:53PM +0100, Hans van Thiel wrote:
> On Sun, 2007-01-21 at 09:42 -0800, Stefan O'Rear wrote:
> > This is the closest you'll get with GHC extensions:
> > 
> > > {-# OPTIONS_GHC -fallow-undecidable-instances #-}
> > > instance Num a => Monoid a where
> > >     e = 0
> > >     add = (+)

> Yes, thank you. The one with the gHC extension looks like what I wanted
> to do, but then in reverse order, declare the numbers to be monoids.
> Expanding on this, I've now got:

In an instance definition, the => is implication; a number is a monoid if
it is a number. (Yes, we know the class syntax is backward :( )

> class Monoid a => Group a where
>    inv :: a -> a 
>    minus :: a-> a -> a
>    minus x y = add x (inv y)
>    inv x = minus e x

> instance Group Int where
>    minus = flip subtract 
> --   inv x = -x
> 
> This seems to work. What I like is that, like in EQ and Ord, functions
> are defined in several ways by default. So, for Int, you can choose to
> define either inv or minus, you don't have to do both.

looks correct

> But subtract and - are defined over all types of Num, so it would be
> nice to have something like
> 
> instance Group a => Num a where .....
> 
> I understand this cannot be done in Haskell98, but it can with the GHC
> extension? Does  {-# OPTIONS_GHC -fallow-undecidable-instances #-} refer
> to possibly infinite definitions? Thanks again!

Almost - that instance definition says that every group is a number (~= ring),
which probably isn't what you meant :)

instance Num a => Group a where .....

Haskell instance definitions, unrestricted, effectively force the compiler
to solve arbitrary logic problems, which can take up to and including forever.
To keep type inference terminating, H98 imposes a number of severe restrictions.
GHC has a number of options to relax the restrictions in ways that complicate
typechecking but don't make it impossible (-fallow-overlapping-instances, etc);
-fallow-undecidable-instances is the ultimate flag and basically says "Do what I
say - I accept responsibility if the typechecker goes into an infinite loop".

Keep SIGINT handy.


More information about the Haskell-Cafe mailing list