[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