Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#294] Add atomicModifyIORef_ and atomicModifyIORef'_ #297

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .hlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2090,6 +2090,18 @@
name: "Use 'writeIORef' from Relude"
note: "'writeIORef' is already exported from Relude"
rhs: writeIORef
- warn:
lhs: "atomicModifyIORef ref (\\a -> (f a, ()))"
rhs: atomicModifyIORef_ ref f
- warn:
lhs: "atomicModifyIORef ref $ \\a -> (f a, ())"
rhs: atomicModifyIORef_ ref f
- warn:
lhs: "atomicModifyIORef' ref $ \\a -> (f a, ())"
rhs: "atomicModifyIORef'_ ref f"
- warn:
lhs: "atomicModifyIORef' ref (\\a -> (f a, ()))"
rhs: "atomicModifyIORef'_ ref f"
- warn:
lhs: Data.Text.IO.getLine
name: "Use 'getLine' from Relude"
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ The changelog is available [on GitHub][2].

* [#228](https://github.com/kowainik/relude/issues/228):
Add `universeNonEmpty` function.
* [#294](https://github.com/kowainik/relude/issues/294):
Add `atomicModifyIORef_` and `atomicModifyIORef'_`.
* [#253](https://github.com/kowainik/relude/issues/253):
Support GHC-8.10. Upgrade GHC-8.8 to 8.8.3.
* [#256](https://github.com/kowainik/relude/issues/256):
Expand Down
4 changes: 4 additions & 0 deletions hlint/hlint.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,10 @@ in [ Rule.Arguments { arguments =
, warnReexport "newIORef" "Data.IORef"
, warnReexport "readIORef" "Data.IORef"
, warnReexport "writeIORef" "Data.IORef"
, warnSimple "atomicModifyIORef ref (\\a -> (f a, ()))" "atomicModifyIORef_ ref f"
, warnSimple "atomicModifyIORef ref $ \\a -> (f a, ())" "atomicModifyIORef_ ref f"
, warnSimple "atomicModifyIORef' ref $ \\a -> (f a, ())" "atomicModifyIORef'_ ref f"
, warnSimple "atomicModifyIORef' ref (\\a -> (f a, ()))" "atomicModifyIORef'_ ref f"
-- Lifted Terminal
, warnReexport "getLine" "Data.Text.IO"

Expand Down
42 changes: 42 additions & 0 deletions src/Relude/Lifted/IORef.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ module Relude.Lifted.IORef
( IORef
, atomicModifyIORef
, atomicModifyIORef'
, atomicModifyIORef_
, atomicModifyIORef'_
, atomicWriteIORef
, modifyIORef
, modifyIORef'
Expand Down Expand Up @@ -81,6 +83,8 @@ writeIORef ref what = liftIO $ Ref.writeIORef ref what
>>> readIORef ref
48

* To avoid space-leaks, see 'modifyIORef'' for stricter updates
* For atomic updates, see 'atomicModifyIORef'
-}
modifyIORef :: MonadIO m => IORef a -> (a -> a) -> m ()
modifyIORef ref how = liftIO $ Ref.modifyIORef ref how
Expand All @@ -94,6 +98,8 @@ modifyIORef ref how = liftIO $ Ref.modifyIORef ref how
>>> readIORef ref
45

* For lazier updates, see 'modifyIORef'
* For atomic updates, see 'atomicModifyIORef''
-}
modifyIORef' :: MonadIO m => IORef a -> (a -> a) -> m ()
modifyIORef' ref how = liftIO $ Ref.modifyIORef' ref how
Expand All @@ -108,6 +114,8 @@ modifyIORef' ref how = liftIO $ Ref.modifyIORef' ref how
>>> readIORef ref
42

* To avoid space-leaks, see 'atomicModifyIORef'' for stricter updates
* If you are not interested in the return value, see 'atomicModifyIORef_'
-}
atomicModifyIORef :: MonadIO m => IORef a -> (a -> (a, b)) -> m b
atomicModifyIORef ref how = liftIO $ Ref.atomicModifyIORef ref how
Expand All @@ -122,12 +130,46 @@ atomicModifyIORef ref how = liftIO $ Ref.atomicModifyIORef ref how
>>> readIORef ref
42

* For lazier updates, see 'atomicModifyIORef'
* If you are not interested in the return value, see 'atomicModifyIORef'_'
-}
atomicModifyIORef' :: MonadIO m => IORef a -> (a -> (a, b)) -> m b
atomicModifyIORef' ref how = liftIO $ Ref.atomicModifyIORef' ref how
{-# INLINE atomicModifyIORef' #-}
{-# SPECIALIZE atomicModifyIORef' :: IORef a -> (a -> (a, b)) -> IO b #-}

{- | Version of 'atomicModifyIORef' that discards return value. Useful
when you want to update 'IORef' but not interested in the returning
result.

>>> ref <- newIORef 42
>>> atomicModifyIORef_ ref (`div` 2)
>>> readIORef ref
21

@since 0.7.0.0
-}
atomicModifyIORef_ :: MonadIO m => IORef a -> (a -> a) -> m ()
atomicModifyIORef_ ref f = atomicModifyIORef ref $ \a -> (f a, ())
{-# INLINE atomicModifyIORef_ #-}
{-# SPECIALIZE atomicModifyIORef_ :: IORef a -> (a -> a) -> IO () #-}

{- | Version of 'atomicModifyIORef'' that discards return value. Useful
when you want to update 'IORef' but not interested in the returning
result.

>>> ref <- newIORef 42
>>> atomicModifyIORef'_ ref (`div` 2)
>>> readIORef ref
21

@since 0.7.0.0
-}
atomicModifyIORef'_ :: MonadIO m => IORef a -> (a -> a) -> m ()
atomicModifyIORef'_ ref f = atomicModifyIORef' ref $ \a -> (f a, ())
{-# INLINE atomicModifyIORef'_ #-}
{-# SPECIALIZE atomicModifyIORef'_ :: IORef a -> (a -> a) -> IO () #-}

{- | Lifted version of 'Ref.atomicWriteIORef'.

>>> ref <- newIORef 42
Expand Down