Skip to content

Instantly share code, notes, and snippets.

@wraikny
Created June 11, 2020 16:53
Show Gist options
  • Save wraikny/9bf2bf95e22fea3874bd8687edfdba03 to your computer and use it in GitHub Desktop.
Save wraikny/9bf2bf95e22fea3874bd8687edfdba03 to your computer and use it in GitHub Desktop.
module DCont =
type DCont<'k, 'a> = ('k -> 'a)
let inline shift (f: ('b -> 'c) -> 'a): DCont<('b -> 'c), 'a> = f
type DContBuilder() =
member inline __.ReturnFrom(m): DCont<'k, 'a> = m
member inline __.Return(x): DCont<'a -> 'b, 'b> = fun k -> k x
member inline __.Bind(x: DCont<'b -> 'c, 'a>, f: 'b -> DCont<'k, 'c>): DCont<'k, 'a> =
(fun k -> x (fun g -> (f g) k))
type ResetBuilder() =
inherit DContBuilder()
member inline __.Run(dcont: DCont<'b -> 'b, 'a>) = dcont id
let dcont = DContBuilder()
let reset = ResetBuilder()
open DCont
let inline get() =
shift(fun k -> fun state -> k state state)
let inline tick() =
shift(fun k -> fun state -> k () (state + 1))
let inline runState init thunk =
init |> reset {
let! result = thunk
return (fun _ -> result)
}
dcont {
do! tick()
do! tick()
let! a = get()
do! tick()
let! b = get()
return b - a
}
|> runState 0
|> printfn "%A"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment