7 people like it.

Coroutine

An implementation of Coroutine by using a continuation monad. It's using a monad library [1]. [1] https://github.com/fsharp/fsharpx

coroutine

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
// requires the monad library
open FSharp.Monad.Continuation
open System.Collections.Generic

type Coroutine() =
    let tasks = Queue<Cont<unit,unit>>()
                
    member this.Put(task) =
        cont {
            do! callCC <| fun exit ->
                task <| callCC (fun c -> 
                tasks.Enqueue(c())
                exit())
            if tasks.Count <> 0 then
                do! tasks.Dequeue()
        } |> tasks.Enqueue

    member this.Run() =
        runCont (tasks.Dequeue()) ignore raise

example

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
let coroutine = Coroutine()

coroutine.Put(fun yield' -> cont {
    printfn "A"
    do! yield'
    printfn "B"
    do! yield'
    printfn "C"
})

coroutine.Put(fun yield' -> cont {
    printfn "1"
    do! yield'
    printfn "2"
})

coroutine.Run()
namespace Microsoft.FSharp
namespace System
namespace System.Collections
namespace System.Collections.Generic
Multiple items
type Coroutine =
  new : unit -> Coroutine
  member Put : task:'b -> 'c
  member Run : unit -> 'a

Full name: Script.Coroutine

--------------------
new : unit -> Coroutine
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
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
val this : Coroutine
member Coroutine.Put : task:'b -> 'c

Full name: Script.Coroutine.Put
val task : 'b
val exit : exitcode:int -> 'T

Full name: Microsoft.FSharp.Core.Operators.exit
member Coroutine.Run : unit -> 'a

Full name: Script.Coroutine.Run
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
val raise : exn:System.Exception -> 'T

Full name: Microsoft.FSharp.Core.Operators.raise
val coroutine : Coroutine

Full name: Script.coroutine
member Coroutine.Put : task:'b -> 'c
val yield' : obj
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
member Coroutine.Run : unit -> 'a

More information

Link:http://fssnip.net/7M
Posted:13 years ago
Author:einblicker
Tags: continuations , coroutine