The intention when using the State monad is to keep state in a purely functional manner without violating referential transparency of functions.

Related Types


#r @"nuget: FSharpPlus"
open FSharpPlus
open FSharpPlus.Data

From Haskell Wiki on State monad

let rec playGame =
    | []-> monad {
            let! (_, score) = State.get
            return score
    | x::xs-> monad {
            let! (on, score) = State.get
            match x with
            | 'a' when on -> do! State.put (on, score + 1)
            | 'b' when on -> do! State.put (on, score - 1)
            | 'c'         -> do! State.put (not on, score)
            | _           -> do! State.put (on, score)
            return! playGame xs

let startState = (false, 0)
let moves = toList "abcaaacbbcabbab"
State.eval (playGame moves) startState
let (score, finalState) = State.run (playGame moves) startState
namespace FSharpPlus
namespace FSharpPlus.Data
val playGame: _arg1: char list -> State<(bool * int),int>
val monad<'monad<'t>> : MonadFxBuilder<'monad<'t>>
<summary> Creates a (lazy) monadic computation expression with side-effects (see http://fsprojects.github.io/FSharpPlus/computation-expressions.html for more information) </summary>
val score: int
Multiple items
union case State.State: ('s -> 't * 's) -> State<'s,'t>

module State from FSharpPlus.Data
<summary> Basic operations on State </summary>

[<Struct>] type State<'s,'t> = | State of ('s -> 't * 's) static member ( *> ) : x: State<'S,'T> * y: State<'S,'U> -> State<'S,'U> static member (<!>) : f: ('T -> 'U) * x: State<'S,'T> -> State<'S,'U> static member ( <* ) : x: State<'S,'U> * y: State<'S,'T> -> State<'S,'U> static member (<*>) : f: State<'S,('T -> 'U)> * x: State<'S,'T> -> State<'S,'U> static member (>=>) : f: ('T -> State<'S,'U>) * g: ('U -> State<'S,'V>) -> ('T -> State<'S,'V>) static member (>>=) : x: State<'S,'T> * f: ('T -> State<'S,'U>) -> State<'S,'U> static member Delay: body: (unit -> State<'S,'T>) -> State<'S,'T> static member Return: a: 'T -> State<'S,'T> static member TryFinally: State<'S,'T> * f: (unit -> unit) -> State<'S,'T> static member TryWith: State<'S,'T> * h: (exn -> State<'S,'T>) -> State<'S,'T> ...
<summary> Computation type: Computations which maintain state. <para> Binding strategy: Threads a state parameter through the sequence of bound functions so that the same state value is never used twice, giving the illusion of in-place update.</para><para> Useful for: Building computations from sequences of operations that require a shared state.</para> The <typeparamref name="'s" /> indicates the computation state, while <typeparamref name="'t" /> indicates the result.</summary>
val get: State<'S,'S>
<summary> Return the state from the internals of the monad. </summary>
val x: char
val xs: char list
val on: bool
val put: x: 'S -> State<'S,unit>
<summary> Replace the state inside the monad. </summary>
val startState: bool * int
val moves: char list
val toList: source: 'a -> 'T list (requires member ToList)
<summary>Builds a list from the given foldable.</summary>
<category index="11">Foldable</category>
<param name="source">The input foldable.</param>
<returns>The list of foldable elements.</returns>
val eval: State<'s,'T> -> s: 's -> 'T
<summary> Evaluates a &lt;paramref name="sa"&gt;state computation&lt;/paramref&gt; with the &lt;paramref name="s"&gt;initial value&lt;/paramref&gt; and return only the result value of the computation. Ignore the final state. </summary>
val finalState: bool * int
val run: State<'S,'T> -> ('S -> 'T * 'S)
<summary> Runs the state with an inital state to get back the result and the new state. </summary>