state.fz
# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation. If not, see <https://www.gnu.org/licenses/>.
# -----------------------------------------------------------------------
#
# Tokiwa Software GmbH, Germany
#
# Source code of Fuzion standard library feature state
#
# Author: Fridtjof Siebert (siebert@tokiwa.software)
#
# -----------------------------------------------------------------------
# state -- represent a state using a monad
#
# this can be used both as plain or as a oneway monad to store a state
# in a way orthogonal to the actual computation.
#
#
public state(
# types of contained and the state value
T, S type,
# the contained value
val T,
# the current state
get S,
redef r effect_mode.val
) : oneway_monad T (state T S) r
is
# monadic operator
#
public redef infix >>= (f T -> state T S) => state.this.bind T f
# monadic operator
#
# Same as non-generic >>=, but also maps to a different type B.
#
public bind (B type, f T -> state B S) state B S =>
f val
# return function
#
public return (a T) => state a get mode
# map this using f
#
public map (B type, f T -> B) state B S =>
state (f val) get mode
# modify the state, leaving the contents unchanged
#
public modify (f S -> S) => state val (f get) mode
# set state to new, leaving the contents unchanged
#
public put (new S) => state val new mode
# converts option to a string
#
# returns the result of $T for an option containing an instance
# of T, alternatively returns $nil for an option that is nil.
#
public redef as_string String =>
"$val ($get)"
# state with 1 argument is short hand for a state containing unit and
# initial_value
#
public state(S type, initial_value S) => state unit initial_value effect_mode.plain
# install new state monad for type S and run r within that state monad
#
# return result of r.
#
public state(S, R type, initial_value S, r ()->R) =>
res option R := nil
state unit S unit initial_value (effect_mode.inst (()->set res := r.call))
res.get
# short-hand for accessing state monad for given type in current environment
#
public state_of(S type) => (state unit S).env
# short-hand for getting state monad for given type in current environment
#
public state_get(S type) => (state_of S).get
# short-hand for modifying state monad for given type in current environment
#
public state_modify(S type, f S->S) => (state_of S).modify f
# short-hand for setting state monad for given type in current environment
#
public state_put(S type, new S) => (state_of S).put new
last changed: 2024-03-07