Algae.State (Algae v1.3.1) View Source
Algae.State
describes a wrapped function that can be used to pass around some
"hidden" pure state.
This has numerous applications, but the primary advantage is purity. The state gets passed around with the value, and the monadic DSL helps it feel more natural than passing everything around by hand.
In many ways, Algae.State
is a generalization of Algae.Reader
and Algae.Writer
.
See Thee Useful Monads
a nice, illustrated guide to how these work and relate.
Anatomy
# To pass in concrete values
↓
%Algae.State{runner: fn access -> {value, state} end}
↑ ↑
# "explicit" value position "hidden" state position
Examples
iex> use Witchcraft
...>
...> %Algae.State{}
...> |> monad do
...> name <- get()
...> let result = "Hello, #{name}!"
...>
...> put result
...> modify &String.upcase/1
...>
...> return result
...> end
...> |> run("world")
{
"Hello, world!",
"HELLO, WORLD!"
}
iex> use Witchcraft
...>
...> pop = fn -> state(fn([x | xs]) -> {x, xs} end) end
...> pull = fn -> state(fn(list = [x | _]) -> {x, list} end) end
...> push = &state(fn(xs) -> {%Witchcraft.Unit{}, [&1 | xs]} end)
...>
...> %Algae.State{}
...> |> monad do
...> push.(["a"])
...> push.(["b"])
...> push.(["c"])
...> push.(["d"])
...> push.(["e"])
...>
...> z <- pop.()
...> y <- pop.()
...> x <- pop.()
...>
...> push.(x <> y <> z)
...> pull.()
...> end
...> |> evaluate([])
["c", "d", "e"]
Link to this section Summary
Functions
Run the enclosed Algae.State
runner, and return the value (no state).
Run the enclosed Algae.State
runner, and return the state (no value).
Set both sides of an Algae.State
struct.
Set both sides of an Algae.State
struct, plus running a function over the
value portion of the inner state.
Run a function over the "state" portion of the runner.
Construct a new Algae.State
struct from a state runner in the form
fn x -> {y, z} end
Set the stateful position of an Algae.Struct
.
Extract the runner from an Algae.State
.
Run an Algae.State
by passing in some initial state to actualy run the enclosed
state runner.
Alias for new/1
that reads better when importing the module.
Link to this section Types
Specs
Specs
t() :: %Algae.State{runner: runner()}
Link to this section Functions
Specs
Specs
Run the enclosed Algae.State
runner, and return the value (no state).
Examples
iex> use Witchcraft
...>
...> %Algae.State{}
...> |> monad do
...> name <- get()
...> put "Ignored"
...> return "Hello, #{name}!"
...> end
...> |> evaluate("world")
"Hello, world!"
Specs
Run the enclosed Algae.State
runner, and return the state (no value).
Examples
iex> fn x -> x + 1 end
...> |> get()
...> |> execute(1)
1
iex> use Witchcraft
...>
...> %Algae.State{}
...> |> monad do
...> whatevs <- get()
...> put "State"
...> return "Hello, #{whatevs}!"
...> end
...> |> execute("world")
"State"
Specs
get() :: t()
Set both sides of an Algae.State
struct.
Examples
iex> run(get(), 1)
{1, 1}
Specs
Set both sides of an Algae.State
struct, plus running a function over the
value portion of the inner state.
Examples
iex> fn x -> x * 10 end
...> |> get()
...> |> run(4)
{40, 4}
Specs
Run a function over the "state" portion of the runner.
Examples
iex> fn x -> x + 1 end
...> |> modify()
...> |> run(42)
{%Witchcraft.Unit{}, 43}
iex> use Witchcraft
...>
...> %Algae.State{}
...> |> monad do
...> name <- get()
...>
...> put "State"
...> modify &String.upcase/1
...>
...> return "Hello, #{name}!"
...> end
...> |> run("world")
{"Hello, world!", "STATE"}
Specs
Construct a new Algae.State
struct from a state runner in the form
fn x -> {y, z} end
Examples
iex> new(fn x -> {x + 1, x} end).runner.(42)
{43, 42}
Specs
Set the stateful position of an Algae.Struct
.
Not unlike Algae.Writer.tell/1
.
Examples
iex> 1
...> |> put()
...> |> run(0)
{%Witchcraft.Unit{}, 1}
Specs
Extract the runner from an Algae.State
.
Can be used as a curried version of run/2
.
Examples
iex> inner = fn x -> {0, x} end
...>
...> run(%Algae.State{runner: inner}).(42) == inner.(42)
true
Specs
Run an Algae.State
by passing in some initial state to actualy run the enclosed
state runner.
Examples
iex> use Witchcraft
...>
...> %Algae.State{}
...> |> of(2)
...> |> run(0)
{2, 0}
Specs
Alias for new/1
that reads better when importing the module.
Examples
iex> state(fn x -> {x + 1, x} end).runner.(42)
{43, 42}