Mark P Jones
Tue, 5 Feb 2002 08:43:18 -0800
The one parameter scheme that you've described breaks down if you want
to generalize further and allow something like:
class RefMonad r m where
new :: a -> m (r a)
read :: r a -> m a
write :: r a -> a -> m ()
instance RefMonad IORef IO where ...
instance RefMonad STRef ST where ...
instance RefMonad Channel IO where ... -- note, this breaks the
instance RefMonad MVar IO where ... -- (m -> r) dependency
instance (RefMonad r m, MonadT t) => RefMonad r (t m) where ...
-- and this kills the
-- (r -> m) dependency
[This is just an example, not a proposal.]
Note the complete lack of functional dependencies. I really don't
think they are the right tool here. Similar uses of fundeps have
appeared in some code for state monads; I don't think they are
appropriate there either. Bidirectional dependencies are occasionally
useful, but, in general, it is also easy to overuse functional
dependencies (the same, I believe, is true for classes in general).
The simpler type structure you describe looks more appealing to me.
All the best,