Skuld.Effects.State (skuld v0.1.13)
View SourceState effect - mutable state threaded through computation.
Supports both simple single-state usage and multiple independent states via tags.
Simple Usage (default tag)
use Skuld.Syntax
alias Skuld.Effects.State
comp do
n <- State.get()
_ <- State.put(n + 1)
n
end
|> State.with_handler(0)
|> Comp.run!()
#=> 0Multiple States (explicit tags)
comp do
_ <- State.put(:counter, 0)
_ <- State.modify(:counter, &(&1 + 1))
count <- State.get(:counter)
_ <- State.put(:name, "alice")
name <- State.get(:name)
{count, name}
end
|> State.with_handler(0, tag: :counter)
|> State.with_handler("", tag: :name)
|> Comp.run!()
#=> {1, "alice"}
Summary
Functions
Get the current state.
Extract the state for the given tag from an env
Get a value derived from the state.
Modify the state with a function, returning the old value.
Replace the state, returning %Change{old: old_state, new: new_state}.
Returns the env.state key used for a given tag.
Install a scoped State handler for a computation.
Functions
@spec get(atom()) :: Skuld.Comp.Types.computation()
Get the current state.
Examples
State.get() # use default tag
State.get(:counter) # use explicit tag
@spec get_state(Skuld.Comp.Types.env(), atom()) :: term()
Extract the state for the given tag from an env
@spec gets((term() -> term())) :: Skuld.Comp.Types.computation()
Get a value derived from the state.
Examples
State.gets(&Map.get(&1, :name)) # use default tag
State.gets(:user, &Map.get(&1, :name)) # use explicit tag
@spec gets(atom(), (term() -> term())) :: Skuld.Comp.Types.computation()
@spec modify((term() -> term())) :: Skuld.Comp.Types.computation()
Modify the state with a function, returning the old value.
Examples
State.modify(&(&1 + 1)) # use default tag
State.modify(:counter, &(&1 + 1)) # use explicit tag
@spec modify(atom(), (term() -> term())) :: Skuld.Comp.Types.computation()
@spec put(term()) :: Skuld.Comp.Types.computation()
Replace the state, returning %Change{old: old_state, new: new_state}.
Examples
State.put(42) # use default tag
State.put(:counter, 42) # use explicit tag
@spec put(atom(), term()) :: Skuld.Comp.Types.computation()
Returns the env.state key used for a given tag.
Useful for configuring EffectLogger's state_keys filter.
Examples
# Only capture State effect data in EffectLogger snapshots
EffectLogger.with_logging(state_keys: [State.state_key(MyApp.Counter)])
# Multiple states
EffectLogger.with_logging(state_keys: [
State.state_key(:counter),
State.state_key(:user)
])
@spec with_handler(Skuld.Comp.Types.computation(), term(), keyword()) :: Skuld.Comp.Types.computation()
Install a scoped State handler for a computation.
Options
tag- the state tag (default:Skuld.Effects.State)output- optional function(result, final_state) -> new_resultto transform the result before returning.
Examples
# Simple usage with default tag
comp do
x <- State.get()
_ <- State.put(x + 1)
x
end
|> State.with_handler(0)
|> Comp.run!()
#=> 0
# With explicit tag
comp do
x <- State.get(:counter)
_ <- State.put(:counter, x + 1)
x
end
|> State.with_handler(0, tag: :counter)
|> Comp.run!()
#=> 0
# Include final state in result
comp do
_ <- State.modify(&(&1 + 1))
:done
end
|> State.with_handler(5, output: fn result, state -> {result, state} end)
|> Comp.run!()
#=> {:done, 6}
# Multiple states
comp do
a <- State.get(:a)
b <- State.get(:b)
{a, b}
end
|> State.with_handler(1, tag: :a)
|> State.with_handler(2, tag: :b)
|> Comp.run!()
#=> {1, 2}