
On Thu, 27 Aug 2020, Olaf Klinke wrote:
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-} import Control.Monad.Reader import Control.Monad.State.Class import Data.IORef
class Monad m => Ref m var where readRef :: var a -> m a writeRef :: var a -> a -> m () modifyRef :: var a -> (a -> a) -> m () modifyRef v f = readRef v >>= (writeRef v . f)
instance Ref IO IORef where readRef = readIORef writeRef = writeIORef modifyRef = modifyIORef
getRef :: Ref m var => ReaderT (var a) m a getRef = ReaderT readRef
putRef :: Ref m var => a -> ReaderT (var a) m () putRef = ReaderT . flip writeRef
instance {-# OVERLAPPING #-} Ref m var => MonadState a (ReaderT (var a) m) where get = getRef put = putRef
I guess, with the "explicit dictionary" trick you do not need an (overlapping) instance at all: http://hackage.haskell.org/package/data-ref-0.0.2/docs/Data-Ref.html