{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} {-# OPTIONS_GHC -Wall #-} ---------------------------------------------------------------------- -- | -- Module : Data.RefMonad -- Copyright : (c) Conal Elliott 2007 -- License : BSD3 -- -- Maintainer : conal@conal.net -- Stability : experimental -- Portability : MPTC -- -- Monads with references, taken from John Hughes's "Global Variables in -- Haskell" (<http://citeseer.ist.psu.edu/473734.html>). -- ---------------------------------------------------------------------- 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 of monads with references. 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 -- | Change the contents of a ref modifyRef :: RefMonad m r => r a -> (a -> a) -> m () modifyRef ref f = readRef ref >>= writeRef ref . f