Packages

A small library that implements the State Monad in gleam

Current section

Files

Jump to
leviathan src leviathan.erl
Raw

src/leviathan.erl

-module(leviathan).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([go/2, eval/2, exec/2, return/1, do/2, get/0, put/1, modify/1, map/2]).
-export_type([state/2]).
-type state(FWC, FWD) :: {state, fun((FWC) -> {FWD, FWC})}.
-spec go(state(FWE, FWF), FWE) -> {FWF, FWE}.
go(St, Initial) ->
(erlang:element(2, St))(Initial).
-spec eval(state(FWI, FWJ), FWI) -> FWJ.
eval(St, Initial) ->
erlang:element(1, go(St, Initial)).
-spec exec(state(FWM, any()), FWM) -> FWM.
exec(St, Initial) ->
erlang:element(2, go(St, Initial)).
-spec return(FWQ) -> state(any(), FWQ).
return(X) ->
{state, fun(S) -> {X, S} end}.
-spec do(state(FWU, FWV), fun((FWV) -> state(FWU, FWY))) -> state(FWU, FWY).
do(St, F) ->
{state, fun(S1) -> case go(St, S1) of
{X, S2} ->
go(F(X), S2)
end end}.
-spec get() -> state(FXD, FXD).
get() ->
{state, fun(S) -> {S, S} end}.
-spec put(FXG) -> state(FXG, nil).
put(X) ->
{state, fun(_) -> {nil, X} end}.
-spec modify(fun((FXJ) -> FXJ)) -> state(FXJ, nil).
modify(F) ->
do(get(), fun(X) -> put(F(X)) end).
-spec map(state(FXM, FXN), fun((FXN) -> FXQ)) -> state(FXM, FXQ).
map(St, F) ->
{state, fun(S1) -> case go(St, S1) of
{X, S2} ->
{F(X), S2}
end end}.