I've just played a bit with Hugs 1.3c which implements the type system that is proposed for Standard Haskell. I came accross a limitation compared to Gofer which I find quite unfortunate. As an example for the advantages of multiple parameter classes Mark Jones gives: class Collection c a where empty :: c a insert :: a -> c a -> c a ... Having the element type of a collection as a parameter enables you to define collections whose elements are restricted, e.g. newtype Set a = Set [a] -- ordered list without duplicates instance Ord a => Collection Set a where empty = Set [] insert = ... -- implementation requires ordering Several people (e.g. Graeme Moss on this mailing list, John Hughes on the Standard Haskell discussion list) have pointed out that it would be nice to do the same thing for monads. Well, in Gofer you can. You just write: class MyMonad m a where myReturn :: a -> m a myBind :: MyMonad m b => m a -> (a -> m b) -> m b instance Ord a => MyMonad Set a where myReturn = \x -> Set [x] myBind = bindSet bindSet :: (Ord a, Ord b) => Set a -> (a -> Set b) -> Set b bindSet = ... However, Hugs 1.3c doesn't like this: ERROR "../test.hs" (line 32): Cannot justify constraints in instance member binding *** expression : myBind *** type : (MyMonad Set a, MyMonad Set b) => Set a -> (a -> Set b) -> Set b *** given context : (MyMonad Set a, MyMonad Set b) *** constraints : Ord b Note that neither Hugs 1.3c nor Gofer have any problems with the type of `myBind' which is (MyMonad m a, MyMonad m b) => m a -> (a -> m b) -> m b The difference lies in the handling of instances. Vividly speaking, Hugs just type checks the body of the instance `MyMonad Set a' under the assumption that `Ord a' is given. Hence it lacks context `Ord b' when type checking `myBind'. Gofer however recognises that every `MyMonad Set a' has an `Ord a' context. Hence the `MyMonad Set b' context of `myBind' implies the existence of `Ord b'. Formally the difference is that the Gofer type system has an additional predicate entailment rule. Any instance definition extends predicate entailment such that the defined instance implies its own context. See Section 8.2.3 of Mark Jones' thesis for details. Mark Jones just introduced this rule for optimisation reasons. In retrospect he considers this rule as bad idea, because it can break data abstraction. I agree with that. However, if the scope of the rule is restricted to the body of the instance, then it certainly does not break data abstraction. The monad example shows how useful the rule can be. I'd like to hear your opinions, Olaf PS: 1. on the Standard Haskell discussion list John Hughes gave a showable and printable monad as another example. 2. implementing the additional rule is a bit of a problem. It requires dictionaries of extensible size. This is no problem for Gofer or Hugs because the internal language is untyped. However, GHC uses FOmega as intermediate language. I found a simple way to code the required form of subtyping in FOmega, but it is not `nice'. -- OLAF CHITIL, Lehrstuhl fuer Informatik II, RWTH Aachen, 52056 Aachen, Germany Tel: (+49/0)241/80-21212; Fax: (+49/0)241/8888-217 URL: http://www-i2.informatik.rwth-aachen.de/~chitil/