From ef6e87270c7b840a00e665fbdb5c10225563e754 Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Wed, 4 Sep 2024 07:04:14 +0200 Subject: [PATCH] Add Effectful.Prim.IORef --- effectful/CHANGELOG.md | 1 + effectful/effectful.cabal | 1 + effectful/src/Effectful/Prim/IORef.hs | 72 +++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 effectful/src/Effectful/Prim/IORef.hs diff --git a/effectful/CHANGELOG.md b/effectful/CHANGELOG.md index 2b7b6e7..cb20e50 100644 --- a/effectful/CHANGELOG.md +++ b/effectful/CHANGELOG.md @@ -8,6 +8,7 @@ `Effectful.Labeled.Writer`. * Add `throwErrorWith` and `throwError_` to `Effectful.Error.Static` and `Effectful.Error.Dynamic`. +* Add `Effectful.Prim.IORef`. * **Breaking changes**: - `localSeqLend`, `localLend`, `localSeqBorrow` and `localBorrow` now take a list of effects instead of a single one. diff --git a/effectful/effectful.cabal b/effectful/effectful.cabal index 965a7ab..c52cdfe 100644 --- a/effectful/effectful.cabal +++ b/effectful/effectful.cabal @@ -96,6 +96,7 @@ library Effectful.FileSystem.IO.ByteString.Builder Effectful.FileSystem.IO.ByteString.Lazy Effectful.FileSystem.IO.File + Effectful.Prim.IORef Effectful.Process Effectful.Temporary Effectful.Timeout diff --git a/effectful/src/Effectful/Prim/IORef.hs b/effectful/src/Effectful/Prim/IORef.hs new file mode 100644 index 0000000..34b1684 --- /dev/null +++ b/effectful/src/Effectful/Prim/IORef.hs @@ -0,0 +1,72 @@ +-- | Lifted "Data.IORef". +-- +-- /Note:/ it requires 'Prim' because @MutVar@ from the @primitive@ library is a +-- generalization of 'IORef'. +-- +-- @since 2.4.0.0 +module Effectful.Prim.IORef + ( -- * Effect + Prim + + -- ** Handlers + , runPrim + + -- * IORef + , IORef + , newIORef + , readIORef + , writeIORef + , modifyIORef + , modifyIORef' + , atomicModifyIORef + , atomicModifyIORef' + , atomicWriteIORef + , mkWeakIORef + ) where + +import Data.IORef (IORef) +import Data.IORef qualified as Ref +import System.Mem.Weak (Weak) + +import Effectful +import Effectful.Dispatch.Static +import Effectful.Dispatch.Static.Primitive +import Effectful.Prim + +-- | Lifted 'Ref.newIORef'. +newIORef :: Prim :> es => a -> Eff es (IORef a) +newIORef = unsafeEff_ . Ref.newIORef + +-- | Lifted 'Ref.readIORef'. +readIORef :: Prim :> es => IORef a -> Eff es a +readIORef = unsafeEff_ . Ref.readIORef + +-- | Lifted 'Ref.writeIORef'. +writeIORef :: Prim :> es => IORef a -> a -> Eff es () +writeIORef var = unsafeEff_ . Ref.writeIORef var + +-- | Lifted 'Ref.modifyIORef'. +modifyIORef :: Prim :> es => IORef a -> (a -> a) -> Eff es () +modifyIORef var = unsafeEff_ . Ref.modifyIORef var + +-- | Lifted 'Ref.modifyIORef''. +modifyIORef' :: Prim :> es => IORef a -> (a -> a) -> Eff es () +modifyIORef' var = unsafeEff_ . Ref.modifyIORef' var + +-- | Lifted 'Ref.atomicModifyIORef'. +atomicModifyIORef :: Prim :> es => IORef a -> (a -> (a, b)) -> Eff es b +atomicModifyIORef var = unsafeEff_ . Ref.atomicModifyIORef var + +-- | Lifted 'Ref.atomicModifyIORef''. +atomicModifyIORef' :: Prim :> es => IORef a -> (a -> (a, b)) -> Eff es b +atomicModifyIORef' var = unsafeEff_ . Ref.atomicModifyIORef' var + +-- | Lifted 'Ref.atomicWriteIORef''. +atomicWriteIORef :: Prim :> es => IORef a -> a -> Eff es () +atomicWriteIORef var = unsafeEff_ . Ref.atomicWriteIORef var + +-- | Lifted 'Ref.mkWeakIORef'. +mkWeakIORef :: Prim :> es => IORef a -> Eff es () -> Eff es (Weak (IORef a)) +mkWeakIORef var f = unsafeEff $ \es -> do + -- The finalizer can run at any point and in any thread. + Ref.mkWeakIORef var . unEff f =<< cloneEnv es