
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.