cleff-0.3.4.0: Fast and concise extensible effects
Copyright(c) 2021 Xy Ren
LicenseBSD3
Maintainerxy.r@outlook.com
Stabilityexperimental
Portabilitynon-portable (GHC only)
Safe HaskellTrustworthy
LanguageHaskell2010

Cleff.State

Description

 
Synopsis

Effect

data State s :: Effect where Source #

An effect capable of providing a mutable state s that can be read and written. This roughly corresponds to the MonadState typeclass and StateT monad transformer in the mtl library.

Constructors

Get :: State s m s 
Put :: s -> State s m () 
State :: (s -> (a, s)) -> State s m a 

Operations

get :: State s :> es => Eff es s Source #

Read the current state.

put :: State s :> es => s -> Eff es () Source #

Update the state with a new value.

state Source #

Arguments

:: State s :> es 
=> (s -> (a, s))

The function that takes the state and returns a result value together with a modified state

-> Eff es a 

Modify the state and produce a value from the state via a function.

gets :: State s :> es => (s -> t) -> Eff es t Source #

Apply a function to the result of get.

modify :: State s :> es => (s -> s) -> Eff es () Source #

Modify the value of the state via a function.

Interpretations

runState :: s -> Eff (State s ': es) a -> Eff es (a, s) Source #

Run the State effect.

Caveats

The runState interpreter is implemented with IORefs and there is no way to do arbitrary atomic transactions. The state operation is atomic though and it is implemented with atomicModifyIORefCAS, which can be faster than atomicModifyIORef in contention. For any more complicated cases of atomicity, please build your own effect that uses either MVars or TVars based on your need.

Unlike mtl, in cleff the state will not revert when an error is thrown.

runState will stop taking care of state operations done on forked threads as soon as the main thread finishes its computation. Any state operation done before main thread finishes is still taken into account.

runStateLocal :: s -> Eff (State s ': es) a -> Eff es (a, s) Source #

Run a State effect where each thread has its thread-local state.

This means that each thread will have an individual state that has the same initial value. Threfore, state operations on one thread will not change the state for any other thread.

The returned final state is that of the current thread.

Caveats

Like runState, the state operation in this handler is atomic. Like runState, and unlike mtl, any errors will not revert the state changes.

Be warned that if you use a thread pool, then when a thread is reused, it may read the state left from the last usage, therefore losing locality. If you use a thread pool, you will want to manually reset the state after each task.

Since: 0.3.3.0

runStateIORef :: IOE :> es => IORef s -> Eff (State s ': es) a -> Eff es a Source #

Run the State effect in terms of operations on a supplied IORef. The state operation is atomic.

Since: 0.2.1.0

runStateMVar :: IOE :> es => MVar s -> Eff (State s ': es) a -> Eff es a Source #

Run the State effect in terms of operations on a supplied MVar.

Since: 0.2.1.0

runStateTVar :: IOE :> es => TVar s -> Eff (State s ': es) a -> Eff es a Source #

Run the State effect in terms of operations on a supplied TVar.

Since: 0.2.1.0

zoom :: State t :> es => Lens' t s -> Eff (State s ': es) ~> Eff es Source #

Run a State effect in terms of a larger State via a Lens'.