うーん、やっぱりキャンセルサポートなしでAsync.Runまで作っても複雑になるなあ・・・。

#light

type Async<'a> = Async of (('a -> unit) * (exn -> unit) -> unit)

let app (Async x) = x

let unit a = Async (fun (cont, _) -> cont a)

let bind m k =
 Async (fun (cont, econt) ->
  let c = fun a -> try app (k a) (cont, econt) with exn -> econt exn
  app m (c, econt))

let catch p =
 Async (fun (cont, _) ->
  app p (cont << Choice2_1, cont << Choice2_2))

let start p = app p ((fun () -> ()), (fun exn -> raise exn))

type Async<'a> with
 static member Run p =
  let res = ref None // val res : Choice<'a, exn> option ref
  let cont = fun r -> res := Some r; unit ()
  start (bind (catch p) cont)
  match Option.get !res with
  | Choice2_1 a -> a
  | Choice2_2 exn -> raise exn

これでAsync.Spawn, Async.Parallelまで挑戦するのは無理ぽ。(´・ω・`)