modify package:base

A slight variation on modifyMVar_ that allows a value to be returned (b) in addition to the modified value of the MVar.
Like modifyMVar, but the IO action in the second argument is executed with asynchronous exceptions masked.
Like modifyMVar_, but the IO action in the second argument is executed with asynchronous exceptions masked.
An exception-safe wrapper for modifying the contents of an MVar. Like withMVar, modifyMVar will replace the original contents of the MVar if an exception is raised during the operation. This function is only atomic if there are no other producers for this MVar. In other words, it cannot guarantee that, by the time modifyMVar_ gets the chance to write to the MVar, the value of the MVar has not been altered by a write operation from another thread.
Mutate the contents of an IORef, combining readIORef and writeIORef. This is not an atomic update, consider using atomicModifyIORef when operating in a multithreaded environment. Be warned that modifyIORef does not apply the function strictly. This means if the program calls modifyIORef many times, but seldom uses the value, thunks will pile up in memory resulting in a space leak. This is a common mistake made when using an IORef as a counter. For example, the following will likely produce a stack overflow:
ref <- newIORef 0
replicateM_ 1000000 $ modifyIORef ref (+1)
readIORef ref >>= print
To avoid this problem, use modifyIORef' instead.
Strict version of modifyIORef. This is not an atomic update, consider using atomicModifyIORef' when operating in a multithreaded environment.
Mutate the contents of an STRef.
>>> :{
runST (do
ref <- newSTRef ""
modifySTRef ref (const "world")
modifySTRef ref (++ "!")
modifySTRef ref ("Hello, " ++)
readSTRef ref )
:}
"Hello, world!"
Be warned that modifySTRef does not apply the function strictly. This means if the program calls modifySTRef many times, but seldom uses the value, thunks will pile up in memory resulting in a space leak. This is a common mistake made when using an STRef as a counter. For example, the following will leak memory and may produce a stack overflow:
>>> import GHC.Internal.Control.Monad (replicateM_)

>>> :{
print (runST (do
ref <- newSTRef 0
replicateM_ 1000 $ modifySTRef ref (+1)
readSTRef ref ))
:}
1000
To avoid this problem, use modifySTRef' instead.
Strict version of modifySTRef
Catch any IOError that occurs in the computation and throw a modified version.
Modify the value of an MVar.
Atomically modifies the contents of an IORef. This function is useful for using IORef in a safe way in a multithreaded program. If you only have one IORef, then using atomicModifyIORef to access and modify it will prevent race conditions. Extending the atomicity to multiple IORefs is problematic, so it is recommended that if you need to do anything more complicated then using MVar instead is a good idea. Conceptually,
atomicModifyIORef ref f = do
-- Begin atomic block
old <- readIORef ref
let r = f old
new = fst r
writeIORef ref new
-- End atomic block
case r of
(_new, res) -> pure res
The actions in the section labeled "atomic block" are not subject to interference from other threads. In particular, it is impossible for the value in the IORef to change between the readIORef and writeIORef invocations. The user-supplied function is applied to the value stored in the IORef, yielding a new value to store in the IORef and a value to return. After the new value is (lazily) stored in the IORef, atomicModifyIORef forces the result pair, but does not force either component of the result. To force both components, use atomicModifyIORef'. Note that
atomicModifyIORef ref (_ -> undefined)
will raise an exception in the calling thread, but will also install the bottoming value in the IORef, where it may be read by other threads. This function imposes a memory barrier, preventing reordering around the "atomic block"; see Data.IORef#memmodel for details.
A strict version of atomicModifyIORef. This forces both the value stored in the IORef and the value returned. Conceptually,
atomicModifyIORef' ref f = do
-- Begin atomic block
old <- readIORef ref
let r = f old
new = fst r
writeIORef ref new
-- End atomic block
case r of
(!_new, !res) -> pure res
The actions in the "atomic block" are not subject to interference by other threads. In particular, the value in the IORef cannot change between the readIORef and writeIORef invocations. The new value is installed in the IORef before either value is forced. So
atomicModifyIORef' ref (x -> (x+1, undefined))
will increment the IORef and then throw an exception in the calling thread.
atomicModifyIORef' ref (x -> (undefined, x))
and
atomicModifyIORef' ref (_ -> undefined)
will each raise an exception in the calling thread, but will also install the bottoming value in the IORef, where it may be read by other threads. This function imposes a memory barrier, preventing reordering around the "atomic block"; see Data.IORef#memmodel for details.
Modify the contents of a MutVar#, returning the previous contents x :: a and the result of applying the given function to the previous contents f x :: c. The data type c (not a newtype!) must be a record whose first field is of lifted type a :: Type and is not unpacked. For example, product types c ~ Solo a or c ~ (a, b) work well. If the record type is both monomorphic and strict in its first field, it's recommended to mark the latter {-# NOUNPACK #-} explicitly. Under the hood atomicModifyMutVar2# atomically replaces a pointer to an old x :: a with a pointer to a selector thunk fst r, where fst is a selector for the first field of the record and r is a function application thunk r = f x. atomicModifyIORef2Native from atomic-modify-general package makes an effort to reflect restrictions on c faithfully, providing a well-typed high-level wrapper.
Modify the contents of a MutVar#, returning the previous contents and the result of applying the given function to the previous contents.
An implementation of the old atomicModifyMutVar# primop in terms of the new atomicModifyMutVar2# primop, for backwards compatibility. The type of this function is a bit bogus. It's best to think of it as having type
atomicModifyMutVar#
:: MutVar# s a
-> (a -> (a, b))
-> State# s
-> (# State# s, b #)
but there may be code that uses this with other two-field record types.
Atomically apply a function to the contents of an IORef and return the old and new values. The result of the function is forced.
Atomically apply a function to the contents of an IORef, installing its first component in the IORef and returning the old contents and the result of applying the function. The result of the function application (the pair) is forced, but neither of its components is.
Atomically apply a function to the contents of an IORef, installing its first component in the IORef and returning the old contents and the result of applying the function. The result of the function application (the pair) is not forced. As a result, this can lead to memory leaks. It is generally better to use atomicModifyIORef2.
Atomically apply a function to the contents of an IORef and return the old and new values. The result of the function is not forced. As this can lead to a memory leak, it is usually better to use atomicModifyIORef'_.
A version of atomicModifyIORef that forces the (pair) result of the function.