[System specific postings aren't normally relayed onto the haskell
 list, but made an exception here since it discusses general
 (Standard) Haskell features. -moderator]  

Are there any plans to implement multiple parameter type classes in Hugs   
any time soon?  I'd really really like them!


I'm trying to learn Haskell by doing some simple computer algebra in the   
language -- this is very interesting, because it mostly maps rather well   
into the language, so the mis-matches are particularly frustrating.

Quite a longish message here -- I've tried to explain where I've found   
snags in the structure of Haskell, so I've also had to explain what I'm   
trying to do with it.


To begin with, I've started with something like this:

> infixl 7 *$
> infixl 6 +$, -$
> class Ring a where
>  (+$), (-$), (*$) :: a -> a -> a
>  negateR :: a -> a
>  fromIntegerR :: Integer -> a
>  zeroR, oneR :: a

It's particularly irritating having to use many of the Num methods and   
therefore having to give them different names. Not a big deal though, but   
it gets more irritating further on.
 For example, I can't now write (to say that ALL Num class instances are   
also Ring instances):

> instance Num a => Ring a where
>  (+$) = (+)
>  ...

Instead, I have to write

> instance Ring Integer where
>  (+$) = (+)
>  ...

and repeat this for every numeric type that I want to work with.  This is   
managable, but it would be nice not to have to.


I've defined my Ring class so that I can now go ahead and define   
polynomials over the ring, for example:

> data Ring a => Poly a = Poly [a]
> instance Ring a => Poly a where ...

This all works very nicely, and I can define a Euclidian domain,   
construct a generic gcd algorithm, construct fields of quotients and so   
forth.


However, I'd now like to add a little bit more structure to things.  In   
particular, I'm going to want to work with modules (vector spaces and the   
like) -- now things start to get messy.
 Firstly, I really should abstract out the abelian group part (+$), so I   
now need to split Ring into two parts:

> class Abelian a where
>  (+$), (-$) :: a -> a -> a
>  negateR :: a -> a
>  zeroR :: a
>
> class Abelian a => Ring a where
>  (*$) :: a -> a -> a
>  oneR :: a
>  fromIntegerR :: Integer -> a

Now I'm faced with something really annoying -- I now have to go through   
all my instance declarations (and you'll remember that I've got lots) --   
and split every single one into two!!!  :(#
 Ok, all done.  Now to declare my module:

> infixl 7 **$
> class (Ring a, Abelian b) => LModule a b where
>  (**$) :: a -> b -> b
> instance Ring a => LModule a a where
>  (**$) = (*$)
> instance Ring a => LModule a (Poly a) where
>  x **$ (Poly ys) = Poly (map (x *$) ys)
> -- and so on ...

ERROR "module.hs" (line 22): Class "LModule" must have exactly one   
argument

Damn, damn, damn.

I'm stuck, am I not?


P.S.  I'm also finding it a bit frustrating having to give every new   
operation a unique name and not being able to rename operations.  I'll   
leave this interesting topic for now...  


Reply via email to