Reference types

Mark P Jones
Tue, 5 Feb 2002 08:43:18 -0800

Hi Simon,

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,