gluon 0.13.1

A static, type inferred programming language for application embedding
Documentation
//! The state monad.

let { Applicative, Functor, Monad } = import! std.prelude

type State s a = s -> { value : a, state : s }

let functor : Functor (State s) =
    rec let map f m : (a -> b) -> State s a -> State s b = \state ->
        let { value, state } = m state
        { value = f value, state = state }

    { map }

let applicative : Applicative (State s) =
    rec let apply mf n : State s (a -> b) -> State s a -> State s b = \state ->
        let { value, state } = mf state
        functor.map value n state
    in
    let wrap value : a -> State s a = \state -> { value, state }

    { functor, apply, wrap }

let monad : Monad (State s) =
    rec let flat_map f m : (a -> State s b) -> State s a -> State s b = \state ->
        let { value, state } = m state
        let m2 = f value
        m2 state

    { applicative, flat_map }

let put value : s -> State s () = \state -> { value = (), state = value }

let get : State s s = \state -> { value = state, state }

let gets f : (s -> a) -> State s a = \state -> { value = f state, state }

let modify f : (s -> s) -> State s () = \state -> { value = (), state = f state }

let runState f state : State s a -> s -> { value : a, state : s } = f state

let evalState f state : State s a -> s -> a = (runState f state).value

let execState f state : State s a -> s -> s = (runState f state).state

{ State, applicative, functor, monad, put, get, modify, runState, evalState, execState }