Multiparameter class confusion

Graham Klyne gk@ninebynine.org
Wed, 04 Jun 2003 13:21:00 +0100


There is a recurring difficulty I'm having using multiparameter classes.

Most recently, I have a class Rule:
[[
class (Expression ex, Eq (rl ex)) => Rule rl ex where
   ...
]]

Which I wish to instantiate for a type GraphClosure via something like:
[[
instance (Label lb, LDGraph lg lb) => Expression (lg lb) where
   ...

data (Label lb, LDGraph lg lb) => GraphClosure lg lb = ...

instance Rule GraphClosure (NSGraph RDFLabel) where
   ...

]]

This gives an error that I think is indicative of a kind error in the use 
of GraphClosure.  If I unbracket the (NSGraph RDFLabel) then the error 
transfers to the use of Rule.

I think that what I really *want* to do here is change the kind of 
GraphClosure to be (* -> *) rather than (* -> * -> *).  But if I try this:

[[
data (Label lb, LDGraph lg lb) => GraphClosure (lg lb) = ...
]]
a syntax error is reported by Hugs and GHC.

If I simply drop lb from the definition of GraphClosure, I get different 
errors because the type lb (and its associated contraint) is significant to 
its implementation

[Later...]

After further trial-and-error, I find that by reversing the arguments to 
GraphClosure and rearranging some other type signatures thus:
[[
data (Label lb, Eq lg) => GraphClosure lb lg = ...
]]
and
[[
instance Rule (GraphClosure RDFLabel) RDFGraph where
]]
I can get things to compile.  But I note that I'm forced to drop the 
LDGraph constraint from the declaration of GraphClosure.

This is all feeling rather like black magic to me.  Does it really all need 
to be this confusing, or am I overlooking some fundamental?

#g


-------------------
Graham Klyne
<GK@NineByNine.org>
PGP: 0FAA 69FF C083 000B A2E9  A131 01B9 1C7A DBCA CB5E