Skip to content

Instantly share code, notes, and snippets.

@Saizan
Created March 18, 2021 12:51
Show Gist options
  • Save Saizan/d87889013fa4f39dc4dc66a0ce9c4797 to your computer and use it in GitHub Desktop.
Save Saizan/d87889013fa4f39dc4dc66a0ce9c4797 to your computer and use it in GitHub Desktop.
module state =
type StateM<'s,'a> = abstract Apply : 's -> ('s -> 'a -> 'r) -> 'r
let mkStateM (f : 's -> 's * 'a) : StateM<'s,'a> =
{ new StateM< 's , 'a > with member __.Apply s k = match f s with (s,a) -> k s a }
let runStateM (m : StateM<'s,'a>) : 's -> 's * 'a = fun s ->
m.Apply s (fun s a -> (s,a))
// defined directly to avoid the value restriction.
let get
= { new StateM< 's , 's > with member __.Apply s k = k s s }
let put s = mkStateM (fun _ -> s , ())
let (>>=) (m : StateM<'s,'a>) (f : 'a -> StateM<'s,'b>) =
{ new StateM<'s , 'b> with
member __.Apply s k =
m.Apply s (fun s a -> let n = f a in n.Apply s k )}
let Return a : StateM<'s,'a> = mkStateM (fun s -> (s,a))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment