Not quite the same complaint, but I've always been bothered by the
inconsistent use of "=>". I would prefer "A => B" to mean "if A, then
B".
that keeps bugging me, too. but switching the implication is not going
to help (although others have proposed the same). here's how I keep
my peace with that anomaly:
> class Monad m => MonadPlus m
if MonadPlus m, then declare Monad m as follows
> instance Integral a => Eq (Ratio a)
if Integral a, then Eq (Ratio a)
> foo :: (Monad m) => [m a] -> m [a]
if Monad m, then foo :: [m a] -> m [a]
the problem is (methinks) that the superclass implication is interpreted
at a different "time/phase" than the others, and classical logic doesn't
have that notion:
1. check Monad m, to ensure that MonadPlus m is a valid declaration
(here, we _check_ that MonadPlus m => Monad m)
2. handle everything else; and since know that we've done 1 first, we
can now _use_ that MonadPlus m => Monad m as well
actually, it is worse: constraints in instances and types just affect the
validity of the thing that follows them, whereas constraints in classes
affect the validity of the whole program.
on the basis of which we can reason "backwards":
- if the program was invalid, I wouldn't be doing this step
- I'm doing this step, so the program is (still) valid
- if the program is valid, so must be the Monad m declaration
- if MonadPlus m is a valid declaration, there must be Monad m
- hence, MonadPlus m => Monad m
so, the reasoning for superclass contexts is backwards, not the
implications. I once argued that it would be quite natural to interpret
the superclass implications in the same way as the other implications
(thus relaxing the constraint that 1 has to be checked globally before
the program can be assumed valid, hence permitting more programs
to be valid).didn't convince the folks I showed it to, so that draft was
never even completed..
cheers,
claus
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://haskell.org/mailman/listinfo/haskell-prime