    {-# LANGUAGE
            MultiParamTypeClasses,
            FlexibleInstances
      #-}

    module Data.Accessor where

    import Data.StateRef.Types

    newtype Getter m a = Getter (m a)
    newtype Setter m a = Setter (a -> m ())
    newtype Accessor m a = Accessor (Getter m a, Setter m a)

    instance Monad m => ReadRef (Getter m a) m a where
        readReference :: Getter m a -> m a
    readReference (Getter m a
    x) = m a
    x

    instance Monad m => WriteRef (Setter m a) m a where
        writeReference :: Setter m a -> a -> m ()
    writeReference (Setter a -> m ()
    f) = a -> m ()
    f

    instance Monad m => ReadRef (Accessor m a) m a where
        readReference :: Accessor m a -> m a
    readReference (Accessor (Getter m a
    x, Setter m a
    _)) = m a
    x
    instance Monad m => WriteRef (Accessor m a) m a where
        writeReference :: Accessor m a -> a -> m ()
    writeReference (Accessor (Getter m a
    _, Setter a -> m ()
    f)) = a -> m ()
    f