Skip to content

Instantly share code, notes, and snippets.

@dsyme
Last active June 22, 2022 14:12
Show Gist options
  • Save dsyme/5557d61a4393577c4fa0f299ca4220f2 to your computer and use it in GitHub Desktop.
Save dsyme/5557d61a4393577c4fa0f299ca4220f2 to your computer and use it in GitHub Desktop.
open System
open System.Threading
open FSharp.Core.CompilerServices.StateMachineHelpers
type Cancellable<'T> =
| Cancellable of (CancellationToken -> Result<'T, exn>)
member inline cf.Invoke(ct: CancellationToken) =
ct.ThrowIfCancellationRequested()
let (Cancellable f) = cf
f ct
type CancellableBuilder () =
member inline _.Delay([<InlineIfLambda>] body: unit -> Cancellable<'T>) =
Cancellable(fun ct ->
let computation = body()
computation.Invoke(ct))
member inline _.Bind(computation1: Cancellable<'T>, [<InlineIfLambda>] continuation: 'T -> Cancellable<'TResult>) =
Cancellable(fun ct ->
__debugPoint ""
let v1 = computation1.Invoke(ct)
match v1 with
| Ok res1 ->
let computation2 = continuation res1
computation2.Invoke(ct)
| Error exn ->
Error exn)
member inline _.Return(v: 'T) =
Cancellable(fun ct ->
__debugPoint ""
Ok v)
let cancellable = CancellableBuilder()
//-------------------------------------------------------
let f1() =
cancellable {
Console.WriteLine("how are you")
return 6
}
let f2(path: bool) =
cancellable {
Console.WriteLine("step1")
let! v1 = f1()
Console.WriteLine("step2, v1 = ", v1)
return v1
}
let computation = f2(true)
let result = computation.Invoke(CancellationToken.None)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment