The intention when using the State monad is to keep state in a purely functional manner without violating referential transparency of functions.
- Reader: Similar but read-only.
open FSharpPlus
open FSharpPlus.Data
From Haskell Wiki on State monad
let rec playGame =
function
| []-> 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 <paramref name="sa">state computation</paramref> with the <paramref name="s">initial value</paramref> 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>