Tue, 5 Feb 2002 07:50:41 -0800
For some time now, GHC and Hugs have had the following=20
families of types and operations:
data IO a
data IORef a
newIORef :: a -> IO (IORef a)
readIORef :: IORef a -> IO a
writeIORef :: IORef a -> a -> IO ()
data ST s a
data STRef s a
newSTRef :: a -> ST s (STRef s a)
readSTRef :: STRef s a -> ST s a
writeSTRef :: STRef s a -> a -> ST s ()
The basic bind operations etc are overloaded for IO and ST,
but to overload the Ref operations one needs to add=20
class RefMonad r m | r -> m, m -> r where
newRef :: a -> m (r a)
readRef :: r a -> m a
writeRef :: r a -> a -> m ()
instance RefMonad IORef IO where ...
instance RefMonad (STRef s) (IO s) where ...
A multi-paramter type class is needed. Notice particularly the
bidirectional functional dependencies. This is the only convincing
example I know with functional dependencies going both ways.
Or at least it was. But in a recent conversation with Peter Thiemann
I realised that this is all baloney. There's a much easier type
data Ref m a -- References in monad m, values of type a
newIORef :: a -> IO (Ref IO a)
readIORef :: Ref IO a -> IO a
writeIORef :: Ref IO a -> a -> IO ()
newSTRef :: a -> ST s (Ref (ST s) a)
readSTRef :: Ref (ST s) a -> ST s a
writeSTRef :: Ref (ST s) a -> a -> ST s ()
class RefMonad m where
newRef :: a -> m (Ref m a)
readRef :: Ref m a -> m a
writeRef :: Ref m a -> a -> m ()
instance RefMonad IO where ...
instance RefMonad (ST s) where ...
No functional dependencies. No multi-parameter classes. Pure Haskell
98. All of this works for mutable arrays too, of course.
I'm sending this to the Haskell list for several reasons.
1. It's a good lesson in "don't use a sledgehammer just becaues
it happens to be to hand".
2. I'd be interested to know of any other examples you have of
*bi-directional* functional depenencies. The above simplification
nukes my only convincing example. (Usually one set of
type variables determines another, but not vice versa.)
Unless there's some technical flaw, this simpler type structure will
be in the new hierarchical Haskell library structure.