Overloading Side-Effects
Why should we choose between IO and ST when we want side-effects?
class Monad m => RefMonad m r | m -> r where
newRef :: a -> ST s (STRef s a)
readRef :: STRef s a -> ST s a
writeRef :: STRef s a -> a -> ST s ()
instance RefMonad IO IORef …
instance RefMonad (ST s) (STRef s) …