
On Fri, Apr 30, 2010 at 11:30 PM, Jason Dagit
On Fri, Apr 30, 2010 at 11:08 PM, Ivan Lazar Miljenovic < ivan.miljenovic@gmail.com> wrote:
You're putting the constraint in the wrong places: put the "(Cls a) => " in the actual functions where you need it.
That's solid advice in general, but it's still not going to work here if any of the functions needed for the instance of Graph require the type class constraint.
The same problem comes up some times with the Monad class. For example, if you wanted to make a monad instance for Set a, you need "(Ord a) => " in the instance functions.
I think associated types can work around this, if Graph used them for the a and b types, but I've never tried that so I don't actually know how it works.
A solution to the monad problem I just mentioned is outlined here as 'restricted monads': http://okmij.org/ftp/Haskell/types.html#restricted-datatypes
Looking over this real quick, I think the Graph class should be changed to mention a and b: class Graph (gr a b) where ... Then your instances would be able to mention constraints: instance Cls a => Graph (GrB a b) where ... Why wasn't the Graph class designed this way? My guess: It was probably a decision that predated multiparameter type classes. Jason