Monad/State.bruijn


# MIT License, Copyright (c) 2024 Marvin Borner
# see samples/fun/rng-state for example usage

:import std/Tuples .
:import std/Combinator .

# scala: s0 ⇒ { (s1, a) = run(s0); (s1, f(a)) }
map [[[1 0 [[1 : (4 0)]]]]] ⧗ (a → b) → (State s a) → (State s b)

…<$>… map

# monadic bind/flat-map operator
# scala: s0 ⇒ { (s1, a) = run(s0); f(a).run(s1) }
bind [[[2 0 [[3 0 1]]]]] ⧗ (State s a) → (a → (State s b)) → (State s b)

…>>=… bind

pure tuple ⧗ a → (State s a)

:test ((w' ∘ c) >>= [(w' ∘ c) >>= [pure 0]] [[0]]) (w' [[0]])
:test ((w' ∘ c) >>= [(w' ∘ c) >>= [pure 0]] [[1]]) (w' [[1]])

get [0 : 0]

gets [[0 : (1 0)]]

put [[1 : Ω]]

puts [[(1 0) : Ω]]

:test (bind get [bind (put ((+2u) 0)) [gets [(+2u) 0]]] (+2u)) ((+4u) : (+16u))

# TODO
ap [0]

# TODO
…<|>… [0]

:input std/Generic/Monad