superclass implications

Claus Reinke claus.reinke at
Wed Feb 22 05:48:02 EST 2006

>>>    >   class Monad m => MonadPlus m    if  <..oops..>
>> if Monad m, then declare MonadPlus m as follows..
> This gloss doesn't make sense. The act of declaration is a constant 
> static property of the module, and cannot be conditional on the property 
> of a variable. The module _always_ declares the class.

would be nice, wouldn't it? and since section 4.3.1 "Class Declarations"
skirts the issue, one might assume that it does (*). but if you look through
4.3.2 "Instance Declarations", you'll find:

    1. .. In other words, T must be an instance of each of C's superclasses 
    and the contexts of all superclass instances must be implied by cx'. 


    If the two instance declarations instead read like this: 
    then the program would be invalid. 

in other words, whether or not the superclass instances exist does not
just affect whether or not the subclass instances exist, it affects whether
or not the instance declaration, and hence the whole program, is valid.
if you don't have any ms for which Monad m holds, you won't be able
to declare any instances of MonadPlus m.

it doesn't matter whether you never use those instances. this program 
is simply not valid (but adding an A Int instance makes so):

    class A x
    class A x => B x 
    instance B Int 

(*) granted, the class declaration alone might still be considered valid, 
but you couldn't actually use it for anything, so I'm not sure that makes 
a difference. and whether or not the instance declaration is statically 
valid _is_ conditional on the existence of other instances.

it is this early/eager checking of superclass constraints that I find odd,
and different from all other constraint handling. it means that I can't use
superclass constraints to lift out common method constraints, because

    class <ctxt> => B x where {m1 :: <t1>;..; mn :: <tn>}

is not equivalent to 

    class B x where {m1 :: <ctxt> => <t1>;..; mn :: <ctxt> => <tn>}

[even if the conditions for variables in contexts would not rule that out]
whereas such lifting is possible for common constraints in instances.

it also means that I have to provide superclass instances at the _point
of declaration_ of subclass instances - I can not defer that obligation
to the _point of use_.


More information about the Haskell-prime mailing list