Skip to content

Instantly share code, notes, and snippets.

@t0yv0

t0yv0/Cont.fs Secret

Created July 30, 2014 14:40
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 t0yv0/0efa00489a0b9b032d48 to your computer and use it in GitHub Desktop.
Save t0yv0/0efa00489a0b9b032d48 to your computer and use it in GitHub Desktop.
type Job<'T> =
| J of (('T -> unit) -> unit)
type JobBuilder =
| Job
member b.Return x =
J (fun k -> k x)
member b.Bind (J runX, f) =
J (fun k ->
runX (fun x ->
let (J runY) = f x
runY k))
member b.Combine (x, y) =
b.Bind (x, fun _ -> y)
member b.Delay f =
J (fun k -> let (J run) = f () in run k)
member b.For (xs: seq<_>, f) =
Job {
let e = xs.GetEnumerator ()
while e.MoveNext () do
do! f e.Current
}
member b.While (cond, J run) =
J (fun k ->
let rec loop () = if cond () then run loop else k ()
loop ())
member b.Zero () =
J (fun k -> k ())
member b.ToAsync (J run) =
Async.FromContinuations (fun (k, _, _) -> run k)
type Cont<'T> =
| C of ('T -> unit)
module Cont =
let callcc f =
J (fun k ->
let kont = C k
let (J run) = f kont
run k)
let throw (C k) v =
J (fun _ -> k v)
module Test =
let search (wanted: 'T -> bool) (list: seq<'T>) : Job<option<'T>> =
Cont.callcc (fun ret ->
Job {
for el in list do
if wanted el then
do! Cont.throw ret (Some el)
return None
})
let main () =
seq {
for i in 1 .. 100 do
do printfn "gen %i" i
yield i
}
|> search (fun x -> x = 10)
|> Job.ToAsync
|> Async.RunSynchronously
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment