Skip to content

Instantly share code, notes, and snippets.

@brianberns
Created March 24, 2019 04:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brianberns/818fae16fbde7b7690b7165fead57ab3 to your computer and use it in GitHub Desktop.
Save brianberns/818fae16fbde7b7690b7165fead57ab3 to your computer and use it in GitHub Desktop.
Computation monad for mortals: A clearly-explained implementation of the continuation monad
/// https://stackoverflow.com/questions/40052256/how-does-continuation-monad-really-work/42062682#42062682
/// A continuation is a function that represents "the rest of the computation".
type Cont<'T, 'U> = ('T -> 'U)
/// An incomplete computation is a function which, when given a continuation,
/// will return a value.
type Inc<'T, 'U> = Cont<'T, 'U> -> 'U
/// Creates an incomplete computation that holds the given value.
let ret (t : 'T) : Inc<'T, _> =
fun (cont : Cont<'T, _>) -> cont t
/// Composition of incomplete computations.
let bind (incT : Inc<'T, _>) (wrap : 'T -> Inc<'U, _>) : Inc<'U, _> =
fun (contU : Cont<'U, _>) -> // return an Inc, which is a function that takes a continuation as input
incT (fun t -> // force the given incomplete computation to cough up its wrapped value
(wrap t) contU) // re-wrap the raw value so it can be sent to the given continuation
/// Monad definition.
type ContinuationBuilder() =
member __.Return(value) = ret value
member __.Bind(inc, wrap) = bind inc wrap
/// Builder instance.
let continuation = ContinuationBuilder()
/// Continuation-ized version of Fibonacci function.
let rec fib n : Inc<int, _> =
continuation {
match n with
| 0 -> return 0
| 1 -> return 1
| n ->
let! x1 = fib (n - 1)
let! x2 = fib (n - 2)
return x1 + x2
}
[<EntryPoint>]
let main argv =
for i = 0 to 10 do
fib i (fun x -> // pass the continuation directly to the fib function
printfn "%d: %d" i x)
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment