{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
{-# OPTIONS_GHC -Wall #-}
module Data.RefMonad (RefMonad(..), modifyRef) where
import Data.IORef (IORef, newIORef, readIORef, writeIORef)
import Data.STRef (STRef, newSTRef, readSTRef, writeSTRef)
import Control.Monad.ST (ST)
class Monad m => RefMonad m r | m -> r where
newRef :: a -> m (r a)
readRef :: r a -> m a
writeRef :: r a -> a -> m ()
instance RefMonad IO IORef where
newRef = newIORef
readRef = readIORef
writeRef = writeIORef
instance RefMonad (ST s) (STRef s) where
newRef = newSTRef
readRef = readSTRef
writeRef = writeSTRef
modifyRef :: RefMonad m r => r a -> (a -> a) -> m ()
modifyRef ref f = readRef ref >>= writeRef ref . f