Skip to content

Commit

Permalink
[#294] Add atomicModifyIORef_ and atomicModifyIORef'_ (#297)
Browse files Browse the repository at this point in the history
Resolves #294
  • Loading branch information
chshersh authored May 14, 2020
1 parent 7eb0ce0 commit 99a4c29
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 0 deletions.
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

0 comments on commit 99a4c29

Please sign in to comment.