7 people like it.
Like the snippet!
Coroutine
An implementation of Coroutine by using a continuation monad. It's using a monad library [1].
[1] https://github.com/fsharp/fsharpx
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
|
module Coroutine
// requires the monad library
open FSharp.Monad.Continuation
open System.Collections.Generic
type Coroutine<'T>() =
let tasks = new Queue<Cont<'T,'T>>()
member this.Put(task) =
let withYield =
callCC <| fun exit ->
task <| fun value ->
callCC <| fun c ->
tasks.Enqueue(c())
exit(value)
tasks.Enqueue(withYield)
member this.Run() =
runCont (tasks.Dequeue()) id raise
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
|
let coroutine = Coroutine()
coroutine.Put(fun yield' -> cont {
do! yield'(1)
do! yield'(2)
return 3
})
coroutine.Put(fun yield' -> cont {
do! yield'(10)
return 20
})
coroutine.Run() |> printfn "%A"
coroutine.Run() |> printfn "%A"
coroutine.Run() |> printfn "%A"
coroutine.Run() |> printfn "%A"
coroutine.Run() |> printfn "%A"
|
module Coroutine
namespace Microsoft.FSharp
namespace System
namespace System.Collections
namespace System.Collections.Generic
Multiple items
type Coroutine<'T> =
new : unit -> Coroutine<'T>
member Put : task:(('a -> 'b) -> 'c) -> 'd
member Run : unit -> 'a
Full name: Coroutine.Coroutine<_>
--------------------
new : unit -> Coroutine<'T>
val tasks : obj
Multiple items
type Queue<'T> =
new : unit -> Queue<'T> + 2 overloads
member Clear : unit -> unit
member Contains : item:'T -> bool
member CopyTo : array:'T[] * arrayIndex:int -> unit
member Count : int
member Dequeue : unit -> 'T
member Enqueue : item:'T -> unit
member GetEnumerator : unit -> Enumerator<'T>
member Peek : unit -> 'T
member ToArray : unit -> 'T[]
...
nested type Enumerator
Full name: System.Collections.Generic.Queue<_>
--------------------
Queue() : unit
Queue(capacity: int) : unit
Queue(collection: IEnumerable<'T>) : unit
val this : Coroutine<'T>
member Coroutine.Put : task:(('a -> 'b) -> 'c) -> 'd
Full name: Coroutine.Coroutine`1.Put
val task : (('a -> 'b) -> 'c)
val withYield : obj
val exit : ('a -> obj)
val value : 'a
val c : obj
member Coroutine.Run : unit -> 'a
Full name: Coroutine.Coroutine`1.Run
val id : x:'T -> 'T
Full name: Microsoft.FSharp.Core.Operators.id
val raise : exn:System.Exception -> 'T
Full name: Microsoft.FSharp.Core.Operators.raise
val coroutine : Coroutine<obj>
Full name: Coroutine.coroutine
member Coroutine.Put : task:(('a -> 'b) -> 'c) -> 'd
val yield' : (obj -> obj)
member Coroutine.Run : unit -> 'a
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
More information