module Gamgine.Lens.IORef where #include "Gamgine/Utils.cpp" IMPORT_LENS_AS_LE import Control.Applicative ((<$>)) import Control.Monad (void) import qualified Control.Monad.State as ST import qualified Data.IORef as R type StateIORef a = ST.StateT (R.IORef a) IO -- | map a function on the value of the IORef mapIORef :: R.IORef a -> (a -> b) -> IO b mapIORef ref f = f <$> R.readIORef ref {- functions to operate on the value of a IORef inside of a State -} -- | get the value of the IORef inside of the State get :: StateIORef a a get = do ref <- ST.get ST.liftIO $ R.readIORef ref -- | apply a function on the value of the IORef gets :: (a -> b) -> StateIORef a b gets f = do ref <- ST.get ST.liftIO $ mapIORef ref f -- | apply the getter lens on the value of the IORef inside of the State getsL :: LE.Lens a b -> StateIORef a b getsL lens = do ref <- ST.get ST.liftIO $ getL ref lens -- | set the value of the IORef inside of the State put :: a -> StateIORef a () put value = do ref <- ST.get ST.liftIO $ R.writeIORef ref value -- | put a value putL :: LE.Lens a b -> b -> StateIORef a () putL lens value = do ref <- ST.get void $ ST.liftIO $ setL ref lens value -- | modify the value of the IORef inside of the State with a lens modify :: (a -> a) -> StateIORef a () modify f = do ref <- ST.get ST.liftIO $ R.modifyIORef ref f -- | modify the value of the IORef inside of the State with a lens modifyL :: LE.Lens a b -> (b -> b) -> StateIORef a () modifyL lens f = do ref <- ST.get ST.liftIO $ modL ref lens f {- functions to apply a lens to the value of a IORef -} -- | apply the getter of the lens on the value of the IORef getL :: R.IORef a -> LE.Lens a b -> IO b getL ref lens = mapIORef ref $ LE.getL lens -- | apply the setter of the lens on the value of the IORef setL :: R.IORef a -> LE.Lens a b -> b -> IO () setL ref lens value = R.modifyIORef ref $ (LE.setL lens value) -- | modify the value of the IORef with a lens modL :: R.IORef a -> LE.Lens a b -> (b -> b) -> IO () modL ref lens f = R.modifyIORef ref $ LE.modL lens f