Resumable Monad


Resumable monad examples

1: 
module Example

Simple resumable calculations

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
open Zero
open ResumableMonad.Multipstep

let x1 = resumable { return 1 }

let x2 = resumable {
    let! y = x1
    return y
}

let example = resumable {
    let! x = resumable { return 1 }
    let! y = resumable { return 2 }
    return x + y
}

let example2 = resumable {
    let! x = example
    let! y = resumable { return 3 }
    return x + y
}

example.resume <| (None, None)
example.resume <| (None, Some 4)

example2.resume <| (None, (None,None), None)
example2.resume <| (Some 3, (None,None), Some 4)

example.resume <| Zero.getZeroTyped<_>

While loop

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
module WhileTest =
    let x = ref 0
    let m =
        resumable {
            printfn "Start"
            while !x<3 do
                printfn "x = %d" !x
                incr x
            printfn "end"
            return !x , true
        }

    let s1 = m.resume (Zero.getZeroTyped<_>)

Another while loop

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
module WhileTest2 =
    let m2 =
        resumable {
            printfn "Start m2"
            let! z, f = WhileTest.m
            printfn "end m2"
            return z+ 100
        }

    let s1 = m2.resume (Zero.getZeroTyped<_>)
    let s2 = m2.resume (Some (54,true))

Resumable service request handler

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
module MyResumableService =
    module Environment =

    (**
    First we need a function called by our service to
    retrieve the details of the request (such as machine name, type of the machine, ...)
    For simplicity here we will assume it's just a machine name.
    *)

        let getMachineName () =
            printfn "Enter name of machine: "
            let machineName = System.Console.ReadLine()
            machineName

    (**
    Now let's define a simple model of the cloud service API used to
    provision new virtual machines. The function below is just a mockup for the real API: it returns
    a random number representing the request ID created by the cloud VM provider.
    *)
        let provisionVM machineName =
            let requestId = System.Random().Next()
            printfn "Provisioning new VM %s in the cloud...." machineName
            printfn "Request ID returned from API is: %d" requestId
            requestId

    (**
    Last we model the cloud API that checks the status of a previously issued request.
    To simulate the processing time normally required for such operation to complete
    we count how many times the function was called and after 5 attempts we return 'success'.
    *)
        let vmRequestSucceeded =
            let waitTime = ref 0
            let rec aux requestId =
                printfn "checking status of request %d (waitTime: %d)" requestId !waitTime
                waitTime := (!waitTime + 1) % 5
                !waitTime = 0
            aux

    let myServiceApi =
        resumable {
            let! machineName = resumable { return Environment.getMachineName () }
            let! requestId = resumable { return Environment.provisionVM machineName }

            let! vmready = resumable {
                while not <| Environment.vmRequestSucceeded requestId do
                    printfn "Waiting for cloud request to complete..."
                    System.Threading.Thread.Sleep(1000)
                return true
            }

            printfn "Request completed for machine %s!" machineName
            return machineName, requestId, vmready
        }

    myServiceApi.resume <| myServiceApi.initial
module Example
module Zero
namespace ResumableMonad
module Multipstep

from ResumableMonad


 Multistep resumable monad where a resumable expression is encoded as a
 mapping from the trace history type 'h to the expression's return type 't.
val x1 : Resumable<int>

Full name: Example.x1
val resumable : ResumableBuilder

Full name: ResumableMonad.Multipstep.resumable
val x2 : Resumable<int option,int>

Full name: Example.x2
val y : int
val example : Resumable<(int option * int option),int>

Full name: Example.example
val x : int
val example2 : Resumable<(int option * (int option * int option) * int option),int>

Full name: Example.example2
member Resumable.resume : h:'h -> 't
union case Option.None: Option<'T>
union case Option.Some: Value: 'T -> Option<'T>
val getZeroTyped<'X> : 'X

Full name: Zero.getZeroTyped
val x : int ref

Full name: Example.WhileTest.x
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
val m : Resumable<int * bool>

Full name: Example.WhileTest.m
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val incr : cell:int ref -> unit

Full name: Microsoft.FSharp.Core.Operators.incr
val s1 : int * bool

Full name: Example.WhileTest.s1
property Resumable.resume: unit -> int * bool
val m2 : Resumable<(int * bool) option,int>

Full name: Example.WhileTest2.m2
val z : int
val f : bool
module WhileTest

from Example
val s1 : int

Full name: Example.WhileTest2.s1
val s2 : int

Full name: Example.WhileTest2.s2
val y : int ref

Full name: Example.IfTest.y
val iftest : Resumable<int * bool>

Full name: Example.IfTest.iftest
val s1 : int * bool

Full name: Example.IfTest.s1
module MyResumableService

from Example
val getMachineName : unit -> string

Full name: Example.MyResumableService.Environment.getMachineName
val machineName : string
namespace System
type Console =
  static member BackgroundColor : ConsoleColor with get, set
  static member Beep : unit -> unit + 1 overload
  static member BufferHeight : int with get, set
  static member BufferWidth : int with get, set
  static member CapsLock : bool
  static member Clear : unit -> unit
  static member CursorLeft : int with get, set
  static member CursorSize : int with get, set
  static member CursorTop : int with get, set
  static member CursorVisible : bool with get, set
  ...

Full name: System.Console
System.Console.ReadLine() : string
val provisionVM : machineName:string -> int

Full name: Example.MyResumableService.Environment.provisionVM
val requestId : int
Multiple items
type Random =
  new : unit -> Random + 1 overload
  member Next : unit -> int + 2 overloads
  member NextBytes : buffer:byte[] -> unit
  member NextDouble : unit -> float

Full name: System.Random

--------------------
System.Random() : unit
System.Random(Seed: int) : unit
val vmRequestSucceeded : (int -> bool)

Full name: Example.MyResumableService.Environment.vmRequestSucceeded
val waitTime : int ref
val aux : (int -> bool)
val myServiceApi : Resumable<(string option * (int option * bool option)),(string * int * bool)>

Full name: Example.MyResumableService.myServiceApi
module Environment

from Example.MyResumableService
val vmready : bool
val not : value:bool -> bool

Full name: Microsoft.FSharp.Core.Operators.not
namespace System.Threading
Multiple items
type Thread =
  inherit CriticalFinalizerObject
  new : start:ThreadStart -> Thread + 3 overloads
  member Abort : unit -> unit + 1 overload
  member ApartmentState : ApartmentState with get, set
  member CurrentCulture : CultureInfo with get, set
  member CurrentUICulture : CultureInfo with get, set
  member DisableComObjectEagerCleanup : unit -> unit
  member ExecutionContext : ExecutionContext
  member GetApartmentState : unit -> ApartmentState
  member GetCompressedStack : unit -> CompressedStack
  member GetHashCode : unit -> int
  ...

Full name: System.Threading.Thread

--------------------
System.Threading.Thread(start: System.Threading.ThreadStart) : unit
System.Threading.Thread(start: System.Threading.ParameterizedThreadStart) : unit
System.Threading.Thread(start: System.Threading.ThreadStart, maxStackSize: int) : unit
System.Threading.Thread(start: System.Threading.ParameterizedThreadStart, maxStackSize: int) : unit
System.Threading.Thread.Sleep(timeout: System.TimeSpan) : unit
System.Threading.Thread.Sleep(millisecondsTimeout: int) : unit
property Resumable.initial: string option * (int option * bool option)


 Returns the empty history (no caching point are initialized)
Fork me on GitHub