6 people like it.

Indexed Monads and Applications in F#

Continuing from Nick Palladinos' session types, this snippet is an implementation of indexed monads in F#, as well as a collection of examples that demonstrate its utility: session types, type-safe serialization and reversible workflows.

  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: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
109: 
110: 
111: 
112: 
113: 
114: 
115: 
116: 
117: 
118: 
119: 
120: 
121: 
122: 
123: 
124: 
125: 
126: 
127: 
128: 
129: 
130: 
131: 
132: 
133: 
134: 
135: 
136: 
137: 
138: 
139: 
140: 
141: 
142: 
143: 
144: 
145: 
146: 
147: 
148: 
149: 
150: 
151: 
152: 
153: 
154: 
155: 
156: 
157: 
158: 
159: 
160: 
161: 
162: 
163: 
164: 
165: 
166: 
167: 
168: 
169: 
170: 
171: 
172: 
173: 
174: 
175: 
176: 
177: 
178: 
179: 
180: 
181: 
182: 
183: 
184: 
185: 
186: 
187: 
188: 
189: 
190: 
191: 
192: 
193: 
194: 
195: 
196: 
197: 
198: 
199: 
200: 
201: 
202: 
203: 
204: 
205: 
206: 
207: 
208: 
209: 
210: 
211: 
212: 
213: 
214: 
215: 
216: 
217: 
218: 
219: 
220: 
221: 
222: 
223: 
224: 
225: 
226: 
227: 
228: 
229: 
230: 
231: 
232: 
233: 
234: 
235: 
236: 
237: 
238: 
239: 
240: 
241: 
242: 
243: 
244: 
245: 
246: 
247: 
248: 
249: 
250: 
251: 
252: 
253: 
254: 
255: 
256: 
257: 
258: 
259: 
260: 
261: 
262: 
263: 
264: 
265: 
266: 
267: 
268: 
269: 
270: 
271: 
272: 
273: 
274: 
275: 
276: 
277: 
278: 
279: 
280: 
281: 
282: 
283: 
284: 
285: 
286: 
287: 
288: 
289: 
290: 
291: 
292: 
293: 
294: 
295: 
296: 
297: 
298: 
299: 
300: 
301: 
302: 
303: 
304: 
305: 
306: 
307: 
308: 
309: 
310: 
311: 
312: 
313: 
314: 
315: 
316: 
317: 
318: 
319: 
320: 
321: 
322: 
323: 
324: 
325: 
326: 
327: 
328: 
329: 
330: 
331: 
332: 
333: 
334: 
335: 
336: 
337: 
338: 
339: 
340: 
341: 
342: 
343: 
344: 
345: 
346: 
347: 
348: 
349: 
350: 
351: 
352: 
353: 
354: 
355: 
356: 
357: 
358: 
359: 
360: 
361: 
362: 
363: 
364: 
365: 
366: 
[<AbstractClass>]
type Index = class end
and Bottom = class inherit Index end
and Indexed<'Tag, 'I1, 'I2, 'T when 'I1 :> Index and 'I2 :> Index> = Func of (unit -> 'T)

let inline run (Func f) = f ()

// Type-level numerals
type Peano = abstract Int : int

let num<'T when 'T :> Peano> = System.Activator.CreateInstance<'T> ()

type Zero () = interface Peano with member __.Int = 0
and Succ<'P when 'P :> Peano> () =
    static let n = num<'P>.Int + 1
    interface Peano with member __.Int = n

type One = Succ<Zero>
type Two = Succ<One>
type Three = Succ<Two>
type Four = Succ<Three>

// fixed iterations type constructor
type Iterate<'Body, 'Iterations when 'Body :> Index and 'Iterations :> Peano> = class inherit Index end

// straightforward implementation of the Indexed monad
type IndexedBuilder<'Tag> () =

    member b.Delay (f : unit -> Indexed<'Tag, 'I1, 'I2, 'T>) = Indexed<'Tag, 'I1, 'I2, 'T>.Func(fun () -> run (f ()))
    member b.Return (x : 'T) = Indexed<'Tag, 'I, 'I, 'T>.Func(fun () -> x)
    member b.ReturnFrom (f : Indexed<'Tag,_,_,_>) = f

    member b.Bind (f : Indexed<'Tag, 'I1, 'I2, 'T>, g : 'T -> Indexed<'Tag, 'I2, 'I3, 'U>) =
        Indexed<'Tag, 'I1, 'I3, 'U>.Func(fun () -> let x = run f in run (g x))

    member b.Combine (f : Indexed<'Tag,_,_,unit>, g : Indexed<_,_,_,_>) = b.Bind(f, fun () -> g)

    member b.For(iters : 'T, bodyF : int -> Indexed<'Tag, 'I1, 'I2, unit>) : Indexed<'Tag, Iterate<'I1, 'T>, 'I2, unit> =
        Func(fun () -> for i = 0 to iters.Int - 1 do run (bodyF i))

// the dual Indexed monad
type DualIndexedBuilder<'Tag> () =

    member b.Delay (f : unit -> Indexed<'Tag, 'I1, 'I2, 'T>) = Indexed<'Tag, 'I1, 'I2, 'T>.Func(fun () -> run (f ()))
    member b.Return (x : 'T) = Indexed<'Tag, 'I, 'I, 'T>.Func(fun () -> x)
    member b.ReturnFrom (f : Indexed<'Tag,_,_,_>) = f

    // composition of indices done with reversed arrows
    member b.Bind (f : Indexed<'Tag, 'I2, 'I1, 'T>, g : 'T -> Indexed<'Tag, 'I3, 'I2, 'U>) =
        Indexed<'Tag, 'I3, 'I1, 'U>.Func(fun () -> let x = run f in run (g x))

    member b.Combine (f : Indexed<'Tag,_,_,unit>, g : Indexed<'Tag,_,_,_>) = b.Bind(f, fun () -> g)

    member b.For(iters : 'Iterations, bodyF : int -> Indexed<'Tag, 'I1, 'I2, unit>) : Indexed<'Tag, Iterate<'I1, 'Iterations>, 'I2, unit> =
        Func(fun () -> for i = iters.Int - 1 downto 0 do run (bodyF i))

// two indexed computations match iff their precomposition and postcomposition indices coincide
type Indexed =
    static member Match (f : Indexed<_, 'I1, 'I2, _>) (g : Indexed<_, 'I1, 'I2, _>) = ()


// Branching

type Branch<'B1, 'B2 when 'B1 :> Index and 'B2 :> Index> = class inherit Index end
type Branch<'B1, 'B2, 'B3 when 'B1 :> Index and 'B2 :> Index and 'B3 :> Index> = class inherit Index end

type Branch =
    static member B1Of2 () = Indexed<'Tag, Branch<'B1, 'B2>, 'B1, unit>.Func id
    static member B2Of2 () = Indexed<'Tag, Branch<'B1, 'B2>, 'B2, unit>.Func id

    static member B1Of3 () = Indexed<'Tag, Branch<'B1, 'B2, 'B3>, 'B1, unit>.Func id
    static member B2Of3 () = Indexed<'Tag, Branch<'B1, 'B2, 'B3>, 'B3, unit>.Func id
    static member B3Of3 () = Indexed<'Tag, Branch<'B1, 'B2, 'B3>, 'B3, unit>.Func id


// Custom Operations

type Op<'Name, 'Rest when 'Rest :> Index> = class inherit Index end
type Op<'Name, 'Param, 'Rest when 'Rest :> Index> = class inherit Index end

type Operation<'Tag, 'Name> =
    static member Do (f : unit -> 'T) = Indexed<'Tag, Op<'Name, 'Rest>, 'Rest, 'T>.Func f

type Operation<'Tag, 'Name, 'Param> =
    static member Do (f : unit -> 'T) = Indexed<'Tag, Op<'Name, 'Param, 'Rest>, 'Rest, 'T>.Func f

//
//  Examples
//

// 1. session types: a rudimentary client-server scheme

type Send = class end
type Receive = class end

type Choose = class end
type Offer = class end

type Channel () =
    let q = new System.Collections.Queue()

    member __.Send (x : 'a) = q.Enqueue x
    member __.Receive<'a> () =
        while q.Count = 0 do System.Threading.Thread.SpinWait 20
        q.Dequeue () :?> 'a

type Client (cc : Channel, sc : Channel) =
    member __.Send (x : 'T) = Operation<Client, Send, 'T>.Do(fun () -> sc.Send x)
    member __.Receive () = Operation<Client, Receive, 'T>.Do(fun () -> cc.Receive<'T>())

    member __.Offer () = Operation<Client, Offer>.Do(fun () -> cc.Receive<bool>())
    member __.Choose (value : bool) = Operation<Client, Choose>.Do(fun () -> sc.Send value)

and Server (cc : Channel, sc : Channel) =
    member __.Send (x : 'T) = Operation<Server, Receive, 'T>.Do(fun () -> cc.Send x)
    member __.Receive () = Operation<Server, Send, 'T>.Do(fun () -> sc.Receive<'T>())

    member __.Choose (value : bool) = Operation<Server, Offer>.Do(fun () -> cc.Send value)
    member __.Offer () = Operation<Server, Choose>.Do(fun () -> sc.Receive<bool>())

and Session () =
    let cc = new Channel()
    let sc = new Channel()

    let client = new Client(cc, sc)
    let server = new Server(cc, sc)
    
    member __.Client = client
    member __.Server = server


let server = new IndexedBuilder<Server> ()
let client = new IndexedBuilder<Client> ()


let df () = Unchecked.defaultof<_>

let runClientServer (clientF : Client -> Indexed<Client,_,Bottom,'T>) (serverF : Server -> Indexed<Server,_,_,_>) =
    // for type checker only
    let attest () = Indexed.Match (clientF (df())) (serverF (df()))

    let session = new Session ()

    [| async { return run (clientF session.Client) :> obj } ; 
       async { return run (serverF session.Server) :> obj } |]
    |> Async.Parallel
    |> Async.RunSynchronously
    |> fun x -> x.[0] :?> 'T


// sample

let clientWorkflow (i : int) (j : int) (self : Client) =
    client {
        do! self.Send i
        do! self.Send j
        let! result = self.Offer ()
        if result then
            do! Branch.B1Of2 ()
            let! msg = self.Receive ()
            do printfn "server replied with error: %s" msg
            return None
        else
            do! Branch.B2Of2 ()
            let! x = self.Receive ()
            return Some x
    }

let serverWorkflow (self : Server) =
    server {
        let! i = self.Receive ()
        let! j = self.Receive ()
        do! self.Choose ((j = 0))
        if j = 0 then
            do! Branch.B1Of2 ()
//            do! self.Send 12 // comment out to create a type error
            do! self.Send "cannot divide by zero!"
        else
            do! Branch.B2Of2 ()
            return! self.Send (i / j)
    }


runClientServer (clientWorkflow 500 2) serverWorkflow
runClientServer (clientWorkflow 500 0) serverWorkflow


// 2. serializers: defining type-safe serialization rules.

open System.IO

type Serialize = class end
type Deserialize = class end

type Primitive = class end

let serializer = new IndexedBuilder<Serialize> ()
let deserializer = new IndexedBuilder<Deserialize> ()

type Writer(m : MemoryStream) =
    do m.Position <- 0L
    let bw = new BinaryWriter(m)

    member __.Write (x : 'T) =
        let write () =
            match box x with
            | :? bool as b -> bw.Write b
            | :? int as n -> bw.Write n
            | :? float as f -> bw.Write f
            | :? string as s -> bw.Write s
            | _ -> invalidArg typeof<'T>.Name "I do not know how to serialize this type."

        Operation<Serialize, Primitive, 'T>.Do write

    member __.Choose1Of2 () = 
        serializer {
            do! Operation<Serialize, Choose>.Do(fun () -> bw.Write true)
            do! Branch.B1Of2 ()
        }

    member __.Choose2Of2 () =
        serializer {
            do! Operation<Serialize, Choose>.Do(fun () -> bw.Write false)
            do! Branch.B2Of2 ()
        }


type Reader(m : MemoryStream) =
    do m.Position <- 0L
    let br = new BinaryReader(m)

    member __.Read () =
        let read () =
            match typeof<'T> with
            | t when t = typeof<bool> -> br.ReadBoolean() :> obj :?> 'T
            | t when t = typeof<int> -> br.ReadInt32() :> obj :?> 'T
            | t when t = typeof<float> -> br.ReadDouble() :> obj :?> 'T
            | t when t = typeof<string> -> br.ReadString() :> obj :?> 'T
            | _ -> invalidArg typeof<'T>.Name "I do not know how to deserialize this type."

        Operation<Deserialize, Primitive, 'T>.Do read

    member __.Offer () = Operation<Deserialize, Choose>.Do(fun () -> br.ReadBoolean())


let runSerializationLoop (ser : 'T -> Writer -> Indexed<Serialize,_,Bottom,_>) (dser : Reader -> Indexed<Deserialize,_,_,'T>) (x : 'T) =
    let attest () = Indexed.Match (ser (df ()) (df())) (dser (df()))
    
    use m = new MemoryStream ()
    run <| ser x (Writer(m))
    run <| dser (Reader(m))


let serialize (c : Choice<'T * 'U, 'S option>) (w : Writer) =
    serializer {
        match c with
        | Choice1Of2 (t,u) ->
            do! w.Choose1Of2 ()

            do! w.Write t
            do! w.Write u

        | Choice2Of2 sOpt ->
            do! w.Choose2Of2 ()

            match sOpt with
            | None ->
                do! w.Choose1Of2 ()
            | Some s ->
                do! w.Choose2Of2 ()
                do! w.Write s
    }

let deserialize (r : Reader) =
    deserializer {
        let! branch = r.Offer ()
        if branch then
            do! Branch.B1Of2 ()

            let! t = r.Read ()
            let! u = r.Read ()

            return Choice1Of2(t, u)
        else
            do! Branch.B2Of2 ()
            let! branch = r.Offer ()
            if branch then
                do! Branch.B1Of2 ()
                return Choice2Of2 None
            else
                do! Branch.B2Of2 ()
                let! s = r.Read()
                return Choice2Of2 (Some s)
    }

let x = Choice2Of2 (Some 3) : Choice<int * string,_>

runSerializationLoop serialize deserialize x


// 3. reversible computation : building workflows that are provably reverse.

// encodes an atomic operation that is reversible by definition
type ReversiblePrimitive =
    {
        Do : unit -> unit
        Undo : unit -> unit
    }

let verbose msg = 
    { 
        Do = fun () -> printfn "doing '%s'." msg
        Undo = fun () -> printfn "undoing '%s'." msg 
    }

type Forward = class end
type Reverse = class end

type Forward<'Name> =
    static member Run (f : ReversiblePrimitive) = Operation<Forward, 'Name>.Do f.Do

type Reverse<'Name> =
    static member Undo (f : ReversiblePrimitive) = Operation<Reverse, 'Name>.Do f.Undo

let forward = new IndexedBuilder<Forward> ()
let reverse = new DualIndexedBuilder<Reverse> ()

let isReverseOf (f : Indexed<Reverse,_,Bottom,_>) (g : Indexed<Forward,_,_,_>) = Indexed.Match g f

type Action1 = class end
type Action2 = class end
type Action3 = class end
type Loop = class end

let install () =
    forward {
        do! Forward<Action1>.Run <| verbose "action 1"
        do! Forward<Action2>.Run <| verbose "action 2"
        do! Forward<Action3>.Run <| verbose "action 3"

        for i in num<Four> do
            do! Forward<Loop>.Run <| verbose (sprintf "Loop, iteration #%d" i)
    }

let uninstall () =
    reverse {

        for i in num<Four> do
            do! Reverse<Loop>.Undo <| verbose (sprintf "Loop, iteration #%d" i)

        do!
            reverse {
                do! reverse {
                    do! Reverse<Action3>.Undo <| verbose "action 3"
                    do! Reverse<Action2>.Undo <| verbose "action 2"
                     
                }
                  
                do! Reverse<Action1>.Undo <| verbose "action 1"
            }
    }

let attest () = isReverseOf (uninstall ()) (install ())

run <| install ()
run <| uninstall ()
Multiple items
type AbstractClassAttribute =
  inherit Attribute
  new : unit -> AbstractClassAttribute

Full name: Microsoft.FSharp.Core.AbstractClassAttribute

--------------------
new : unit -> AbstractClassAttribute
type Index

Full name: Script.Index
type Bottom =
  inherit Index

Full name: Script.Bottom
type Indexed<'Tag,'I1,'I2,'T (requires 'I1 :> Index and 'I2 :> Index)> = | Func of (unit -> 'T)

Full name: Script.Indexed<_,_,_,_>
union case Indexed.Func: (unit -> 'T) -> Indexed<'Tag,'I1,'I2,'T>
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
val run : Indexed<'a,#Index,#Index,'d> -> 'd

Full name: Script.run
val f : (unit -> 'd)
type Peano =
  interface
    abstract member Int : int
  end

Full name: Script.Peano
abstract member Peano.Int : int

Full name: Script.Peano.Int
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
val num<'T (requires 'T :> Peano)> : #Peano

Full name: Script.num
namespace System
type Activator =
  static member CreateComInstanceFrom : assemblyName:string * typeName:string -> ObjectHandle + 1 overload
  static member CreateInstance<'T> : unit -> 'T + 15 overloads
  static member CreateInstanceFrom : assemblyFile:string * typeName:string -> ObjectHandle + 6 overloads
  static member GetObject : type:Type * url:string -> obj + 1 overload

Full name: System.Activator
System.Activator.CreateInstance<'T>() : 'T
   (+0 other overloads)
System.Activator.CreateInstance(activationContext: System.ActivationContext) : System.Runtime.Remoting.ObjectHandle
   (+0 other overloads)
System.Activator.CreateInstance(type: System.Type) : obj
   (+0 other overloads)
System.Activator.CreateInstance(activationContext: System.ActivationContext, activationCustomData: string []) : System.Runtime.Remoting.ObjectHandle
   (+0 other overloads)
System.Activator.CreateInstance(type: System.Type, nonPublic: bool) : obj
   (+0 other overloads)
System.Activator.CreateInstance(assemblyName: string, typeName: string) : System.Runtime.Remoting.ObjectHandle
   (+0 other overloads)
System.Activator.CreateInstance(type: System.Type, [<System.ParamArray>] args: obj []) : obj
   (+0 other overloads)
System.Activator.CreateInstance(domain: System.AppDomain, assemblyName: string, typeName: string) : System.Runtime.Remoting.ObjectHandle
   (+0 other overloads)
System.Activator.CreateInstance(assemblyName: string, typeName: string, activationAttributes: obj []) : System.Runtime.Remoting.ObjectHandle
   (+0 other overloads)
System.Activator.CreateInstance(type: System.Type, args: obj [], activationAttributes: obj []) : obj
   (+0 other overloads)
Multiple items
type Zero =
  interface Peano
  new : unit -> Zero

Full name: Script.Zero

--------------------
new : unit -> Zero
override Zero.Int : int

Full name: Script.Zero.Int
Multiple items
type Succ<'P (requires 'P :> Peano)> =
  interface Peano
  new : unit -> Succ<'P>

Full name: Script.Succ<_>

--------------------
new : unit -> Succ<'P>
val n : int
override Succ.Int : int

Full name: Script.Succ`1.Int
type One = Succ<Zero>

Full name: Script.One
type Two = Succ<One>

Full name: Script.Two
type Three = Succ<Two>

Full name: Script.Three
type Four = Succ<Three>

Full name: Script.Four
type Iterate<'Body,'Iterations (requires 'Body :> Index and 'Iterations :> Peano)> =
  inherit Index

Full name: Script.Iterate<_,_>
Multiple items
type IndexedBuilder<'Tag> =
  new : unit -> IndexedBuilder<'Tag>
  member Bind : f:Indexed<'Tag,'I1,'I2,'T> * g:('T -> Indexed<'Tag,'I2,'I3,'U>) -> Indexed<'Tag,'I1,'I3,'U> (requires 'I1 :> Index and 'I2 :> Index and 'I3 :> Index)
  member Combine : f:Indexed<'Tag,'a,'b,unit> * g:Indexed<'Tag,'b,'c,'d> -> Indexed<'Tag,'a,'c,'d> (requires 'a :> Index and 'b :> Index and 'c :> Index)
  member Delay : f:(unit -> Indexed<'Tag,'I1,'I2,'T>) -> Indexed<'Tag,'I1,'I2,'T> (requires 'I1 :> Index and 'I2 :> Index)
  member For : iters:'T * bodyF:(int -> Indexed<'Tag,'I1,'I2,unit>) -> Indexed<'Tag,Iterate<'I1,'T>,'I2,unit> (requires 'T :> Peano and 'I1 :> Index and 'I2 :> Index)
  member Return : x:'T -> Indexed<'Tag,'I,'I,'T> (requires 'I :> Index)
  member ReturnFrom : f:Indexed<'Tag,'a,'b,'c> -> Indexed<'Tag,'a,'b,'c> (requires 'a :> Index and 'b :> Index)

Full name: Script.IndexedBuilder<_>

--------------------
new : unit -> IndexedBuilder<'Tag>
val b : IndexedBuilder<'Tag>
member IndexedBuilder.Delay : f:(unit -> Indexed<'Tag,'I1,'I2,'T>) -> Indexed<'Tag,'I1,'I2,'T> (requires 'I1 :> Index and 'I2 :> Index)

Full name: Script.IndexedBuilder`1.Delay
val f : (unit -> Indexed<'Tag,#Index,#Index,'T>)
member IndexedBuilder.Return : x:'T -> Indexed<'Tag,'I,'I,'T> (requires 'I :> Index)

Full name: Script.IndexedBuilder`1.Return
val x : 'T
member IndexedBuilder.ReturnFrom : f:Indexed<'Tag,'a,'b,'c> -> Indexed<'Tag,'a,'b,'c> (requires 'a :> Index and 'b :> Index)

Full name: Script.IndexedBuilder`1.ReturnFrom
val f : Indexed<'Tag,#Index,#Index,'c>
member IndexedBuilder.Bind : f:Indexed<'Tag,'I1,'I2,'T> * g:('T -> Indexed<'Tag,'I2,'I3,'U>) -> Indexed<'Tag,'I1,'I3,'U> (requires 'I1 :> Index and 'I2 :> Index and 'I3 :> Index)

Full name: Script.IndexedBuilder`1.Bind
val f : Indexed<'Tag,#Index,#Index,'T>
val g : ('T -> Indexed<'Tag,#Index,#Index,'U>)
member IndexedBuilder.Combine : f:Indexed<'Tag,'a,'b,unit> * g:Indexed<'Tag,'b,'c,'d> -> Indexed<'Tag,'a,'c,'d> (requires 'a :> Index and 'b :> Index and 'c :> Index)

Full name: Script.IndexedBuilder`1.Combine
val f : Indexed<'Tag,#Index,#Index,unit>
val g : Indexed<'Tag,#Index,#Index,'d>
member IndexedBuilder.Bind : f:Indexed<'Tag,'I1,'I2,'T> * g:('T -> Indexed<'Tag,'I2,'I3,'U>) -> Indexed<'Tag,'I1,'I3,'U> (requires 'I1 :> Index and 'I2 :> Index and 'I3 :> Index)
member IndexedBuilder.For : iters:'T * bodyF:(int -> Indexed<'Tag,'I1,'I2,unit>) -> Indexed<'Tag,Iterate<'I1,'T>,'I2,unit> (requires 'T :> Peano and 'I1 :> Index and 'I2 :> Index)

Full name: Script.IndexedBuilder`1.For
val iters : #Peano
val bodyF : (int -> Indexed<'Tag,#Index,#Index,unit>)
val i : int
property Peano.Int: int
Multiple items
type DualIndexedBuilder<'Tag> =
  new : unit -> DualIndexedBuilder<'Tag>
  member Bind : f:Indexed<'Tag,'I2,'I1,'T> * g:('T -> Indexed<'Tag,'I3,'I2,'U>) -> Indexed<'Tag,'I3,'I1,'U> (requires 'I2 :> Index and 'I1 :> Index and 'I3 :> Index)
  member Combine : f:Indexed<'Tag,'a,'b,unit> * g:Indexed<'Tag,'c,'a,'d> -> Indexed<'Tag,'c,'b,'d> (requires 'a :> Index and 'b :> Index and 'c :> Index)
  member Delay : f:(unit -> Indexed<'Tag,'I1,'I2,'T>) -> Indexed<'Tag,'I1,'I2,'T> (requires 'I1 :> Index and 'I2 :> Index)
  member For : iters:'Iterations * bodyF:(int -> Indexed<'Tag,'I1,'I2,unit>) -> Indexed<'Tag,Iterate<'I1,'Iterations>,'I2,unit> (requires 'Iterations :> Peano and 'I1 :> Index and 'I2 :> Index)
  member Return : x:'T -> Indexed<'Tag,'I,'I,'T> (requires 'I :> Index)
  member ReturnFrom : f:Indexed<'Tag,'a,'b,'c> -> Indexed<'Tag,'a,'b,'c> (requires 'a :> Index and 'b :> Index)

Full name: Script.DualIndexedBuilder<_>

--------------------
new : unit -> DualIndexedBuilder<'Tag>
val b : DualIndexedBuilder<'Tag>
member DualIndexedBuilder.Delay : f:(unit -> Indexed<'Tag,'I1,'I2,'T>) -> Indexed<'Tag,'I1,'I2,'T> (requires 'I1 :> Index and 'I2 :> Index)

Full name: Script.DualIndexedBuilder`1.Delay
member DualIndexedBuilder.Return : x:'T -> Indexed<'Tag,'I,'I,'T> (requires 'I :> Index)

Full name: Script.DualIndexedBuilder`1.Return
member DualIndexedBuilder.ReturnFrom : f:Indexed<'Tag,'a,'b,'c> -> Indexed<'Tag,'a,'b,'c> (requires 'a :> Index and 'b :> Index)

Full name: Script.DualIndexedBuilder`1.ReturnFrom
member DualIndexedBuilder.Bind : f:Indexed<'Tag,'I2,'I1,'T> * g:('T -> Indexed<'Tag,'I3,'I2,'U>) -> Indexed<'Tag,'I3,'I1,'U> (requires 'I2 :> Index and 'I1 :> Index and 'I3 :> Index)

Full name: Script.DualIndexedBuilder`1.Bind
member DualIndexedBuilder.Combine : f:Indexed<'Tag,'a,'b,unit> * g:Indexed<'Tag,'c,'a,'d> -> Indexed<'Tag,'c,'b,'d> (requires 'a :> Index and 'b :> Index and 'c :> Index)

Full name: Script.DualIndexedBuilder`1.Combine
member DualIndexedBuilder.Bind : f:Indexed<'Tag,'I2,'I1,'T> * g:('T -> Indexed<'Tag,'I3,'I2,'U>) -> Indexed<'Tag,'I3,'I1,'U> (requires 'I2 :> Index and 'I1 :> Index and 'I3 :> Index)
member DualIndexedBuilder.For : iters:'Iterations * bodyF:(int -> Indexed<'Tag,'I1,'I2,unit>) -> Indexed<'Tag,Iterate<'I1,'Iterations>,'I2,unit> (requires 'Iterations :> Peano and 'I1 :> Index and 'I2 :> Index)

Full name: Script.DualIndexedBuilder`1.For
Multiple items
type Indexed =
  static member Match : f:Indexed<'a,'I1,'I2,'b> -> g:Indexed<'c,'I1,'I2,'d> -> unit (requires 'I1 :> Index and 'I2 :> Index)

Full name: Script.Indexed

--------------------
type Indexed<'Tag,'I1,'I2,'T (requires 'I1 :> Index and 'I2 :> Index)> = | Func of (unit -> 'T)

Full name: Script.Indexed<_,_,_,_>
static member Indexed.Match : f:Indexed<'a,'I1,'I2,'b> -> g:Indexed<'c,'I1,'I2,'d> -> unit (requires 'I1 :> Index and 'I2 :> Index)

Full name: Script.Indexed.Match
val f : Indexed<'a,#Index,#Index,'b>
val g : Indexed<'c,#Index,#Index,'d>
type Branch<'B1,'B2 (requires 'B1 :> Index and 'B2 :> Index)> =
  inherit Index

Full name: Script.Branch<_,_>
Multiple items
type Branch<'B1,'B2 (requires 'B1 :> Index and 'B2 :> Index)> =
  inherit Index

Full name: Script.Branch<_,_>

--------------------
type Branch<'B1,'B2,'B3 (requires 'B1 :> Index and 'B2 :> Index and 'B3 :> Index)> =
  inherit Index

Full name: Script.Branch<_,_,_>
Multiple items
type Branch =
  static member B1Of2 : unit -> Indexed<'Tag,Branch<'B1,#Index>,'B1,unit> (requires 'B1 :> Index)
  static member B1Of3 : unit -> Indexed<'Tag,Branch<'B1,#Index,#Index>,'B1,unit> (requires 'B1 :> Index)
  static member B2Of2 : unit -> Indexed<'Tag,Branch<#Index,'B2>,'B2,unit> (requires 'B2 :> Index)
  static member B2Of3 : unit -> Indexed<'Tag,Branch<#Index,#Index,'B3>,'B3,unit> (requires 'B3 :> Index)
  static member B3Of3 : unit -> Indexed<'Tag,Branch<#Index,#Index,'B3>,'B3,unit> (requires 'B3 :> Index)

Full name: Script.Branch

--------------------
type Branch<'B1,'B2 (requires 'B1 :> Index and 'B2 :> Index)> =
  inherit Index

Full name: Script.Branch<_,_>

--------------------
type Branch<'B1,'B2,'B3 (requires 'B1 :> Index and 'B2 :> Index and 'B3 :> Index)> =
  inherit Index

Full name: Script.Branch<_,_,_>
static member Branch.B1Of2 : unit -> Indexed<'Tag,Branch<'B1,#Index>,'B1,unit> (requires 'B1 :> Index)

Full name: Script.Branch.B1Of2
val id : x:'T -> 'T

Full name: Microsoft.FSharp.Core.Operators.id
static member Branch.B2Of2 : unit -> Indexed<'Tag,Branch<#Index,'B2>,'B2,unit> (requires 'B2 :> Index)

Full name: Script.Branch.B2Of2
static member Branch.B1Of3 : unit -> Indexed<'Tag,Branch<'B1,#Index,#Index>,'B1,unit> (requires 'B1 :> Index)

Full name: Script.Branch.B1Of3
static member Branch.B2Of3 : unit -> Indexed<'Tag,Branch<#Index,#Index,'B3>,'B3,unit> (requires 'B3 :> Index)

Full name: Script.Branch.B2Of3
static member Branch.B3Of3 : unit -> Indexed<'Tag,Branch<#Index,#Index,'B3>,'B3,unit> (requires 'B3 :> Index)

Full name: Script.Branch.B3Of3
type Op<'Name,'Rest (requires 'Rest :> Index)> =
  inherit Index

Full name: Script.Op<_,_>
Multiple items
type Op<'Name,'Rest (requires 'Rest :> Index)> =
  inherit Index

Full name: Script.Op<_,_>

--------------------
type Op<'Name,'Param,'Rest (requires 'Rest :> Index)> =
  inherit Index

Full name: Script.Op<_,_,_>
type Operation<'Tag,'Name> =
  static member Do : f:(unit -> 'T) -> Indexed<'Tag,Op<'Name,'Rest>,'Rest,'T> (requires 'Rest :> Index)

Full name: Script.Operation<_,_>
static member Operation.Do : f:(unit -> 'T) -> Indexed<'Tag,Op<'Name,'Rest>,'Rest,'T> (requires 'Rest :> Index)

Full name: Script.Operation`2.Do
val f : (unit -> 'T)
Multiple items
type Operation<'Tag,'Name> =
  static member Do : f:(unit -> 'T) -> Indexed<'Tag,Op<'Name,'Rest>,'Rest,'T> (requires 'Rest :> Index)

Full name: Script.Operation<_,_>

--------------------
type Operation<'Tag,'Name,'Param> =
  static member Do : f:(unit -> 'T) -> Indexed<'Tag,Op<'Name,'Param,'Rest>,'Rest,'T> (requires 'Rest :> Index)

Full name: Script.Operation<_,_,_>
static member Operation.Do : f:(unit -> 'T) -> Indexed<'Tag,Op<'Name,'Param,'Rest>,'Rest,'T> (requires 'Rest :> Index)

Full name: Script.Operation`3.Do
type Send

Full name: Script.Send
type Receive

Full name: Script.Receive
type Choose

Full name: Script.Choose
type Offer

Full name: Script.Offer
Multiple items
type Channel =
  new : unit -> Channel
  member Receive : unit -> 'a
  member Send : x:'a -> unit

Full name: Script.Channel

--------------------
new : unit -> Channel
val q : System.Collections.Queue
namespace System.Collections
Multiple items
type Queue =
  new : unit -> Queue + 3 overloads
  member Clear : unit -> unit
  member Clone : unit -> obj
  member Contains : obj:obj -> bool
  member CopyTo : array:Array * index:int -> unit
  member Count : int
  member Dequeue : unit -> obj
  member Enqueue : obj:obj -> unit
  member GetEnumerator : unit -> IEnumerator
  member IsSynchronized : bool
  ...

Full name: System.Collections.Queue

--------------------
System.Collections.Queue() : unit
System.Collections.Queue(capacity: int) : unit
System.Collections.Queue(col: System.Collections.ICollection) : unit
System.Collections.Queue(capacity: int, growFactor: float32) : unit
Multiple items
member Channel.Send : x:'a -> unit

Full name: Script.Channel.Send

--------------------
type Send

Full name: Script.Send
val x : 'a
System.Collections.Queue.Enqueue(obj: obj) : unit
val __ : Channel
Multiple items
member Channel.Receive : unit -> 'a

Full name: Script.Channel.Receive

--------------------
type Receive

Full name: Script.Receive
property System.Collections.Queue.Count: int
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.SpinWait(iterations: int) : unit
System.Collections.Queue.Dequeue() : obj
Multiple items
type Client =
  new : cc:Channel * sc:Channel -> Client
  member Choose : value:bool -> Indexed<Client,Op<Choose,'e>,'e,unit> (requires 'e :> Index)
  member Offer : unit -> Indexed<Client,Op<Offer,'f>,'f,bool> (requires 'f :> Index)
  member Receive : unit -> Indexed<Client,Op<Receive,'T,'g>,'g,'T> (requires 'g :> Index)
  member Send : x:'T -> Indexed<Client,Op<Send,'T,'h>,'h,unit> (requires 'h :> Index)

Full name: Script.Client

--------------------
new : cc:Channel * sc:Channel -> Client
val cc : Channel
val sc : Channel
Multiple items
member Client.Send : x:'T -> Indexed<Client,Op<Send,'T,'h>,'h,unit> (requires 'h :> Index)

Full name: Script.Client.Send

--------------------
type Send

Full name: Script.Send
member Channel.Send : x:'a -> unit
val __ : Client
Multiple items
member Client.Receive : unit -> Indexed<Client,Op<Receive,'T,'g>,'g,'T> (requires 'g :> Index)

Full name: Script.Client.Receive

--------------------
type Receive

Full name: Script.Receive
member Channel.Receive : unit -> 'a
Multiple items
member Client.Offer : unit -> Indexed<Client,Op<Offer,'f>,'f,bool> (requires 'f :> Index)

Full name: Script.Client.Offer

--------------------
type Offer

Full name: Script.Offer
type bool = System.Boolean

Full name: Microsoft.FSharp.Core.bool
Multiple items
member Client.Choose : value:bool -> Indexed<Client,Op<Choose,'e>,'e,unit> (requires 'e :> Index)

Full name: Script.Client.Choose

--------------------
type Choose

Full name: Script.Choose
val value : bool
Multiple items
type Server =
  new : cc:Channel * sc:Channel -> Server
  member Choose : value:bool -> Indexed<Server,Op<Offer,'b>,'b,unit> (requires 'b :> Index)
  member Offer : unit -> Indexed<Server,Op<Choose,'a>,'a,bool> (requires 'a :> Index)
  member Receive : unit -> Indexed<Server,Op<Send,'T,'c>,'c,'T> (requires 'c :> Index)
  member Send : x:'T -> Indexed<Server,Op<Receive,'T,'d>,'d,unit> (requires 'd :> Index)

Full name: Script.Server

--------------------
new : cc:Channel * sc:Channel -> Server
Multiple items
member Server.Send : x:'T -> Indexed<Server,Op<Receive,'T,'d>,'d,unit> (requires 'd :> Index)

Full name: Script.Server.Send

--------------------
type Send

Full name: Script.Send
val __ : Server
Multiple items
member Server.Receive : unit -> Indexed<Server,Op<Send,'T,'c>,'c,'T> (requires 'c :> Index)

Full name: Script.Server.Receive

--------------------
type Receive

Full name: Script.Receive
Multiple items
member Server.Choose : value:bool -> Indexed<Server,Op<Offer,'b>,'b,unit> (requires 'b :> Index)

Full name: Script.Server.Choose

--------------------
type Choose

Full name: Script.Choose
Multiple items
member Server.Offer : unit -> Indexed<Server,Op<Choose,'a>,'a,bool> (requires 'a :> Index)

Full name: Script.Server.Offer

--------------------
type Offer

Full name: Script.Offer
Multiple items
type Session =
  new : unit -> Session
  member Client : Client
  member Server : Server

Full name: Script.Session

--------------------
new : unit -> Session
val client : Client
val server : Server
Multiple items
member Session.Client : Client

Full name: Script.Session.Client

--------------------
type Client =
  new : cc:Channel * sc:Channel -> Client
  member Choose : value:bool -> Indexed<Client,Op<Choose,'e>,'e,unit> (requires 'e :> Index)
  member Offer : unit -> Indexed<Client,Op<Offer,'f>,'f,bool> (requires 'f :> Index)
  member Receive : unit -> Indexed<Client,Op<Receive,'T,'g>,'g,'T> (requires 'g :> Index)
  member Send : x:'T -> Indexed<Client,Op<Send,'T,'h>,'h,unit> (requires 'h :> Index)

Full name: Script.Client

--------------------
new : cc:Channel * sc:Channel -> Client
val __ : Session
Multiple items
member Session.Server : Server

Full name: Script.Session.Server

--------------------
type Server =
  new : cc:Channel * sc:Channel -> Server
  member Choose : value:bool -> Indexed<Server,Op<Offer,'b>,'b,unit> (requires 'b :> Index)
  member Offer : unit -> Indexed<Server,Op<Choose,'a>,'a,bool> (requires 'a :> Index)
  member Receive : unit -> Indexed<Server,Op<Send,'T,'c>,'c,'T> (requires 'c :> Index)
  member Send : x:'T -> Indexed<Server,Op<Receive,'T,'d>,'d,unit> (requires 'd :> Index)

Full name: Script.Server

--------------------
new : cc:Channel * sc:Channel -> Server
val server : IndexedBuilder<Server>

Full name: Script.server
val client : IndexedBuilder<Client>

Full name: Script.client
val df : unit -> 'a

Full name: Script.df
module Unchecked

from Microsoft.FSharp.Core.Operators
val defaultof<'T> : 'T

Full name: Microsoft.FSharp.Core.Operators.Unchecked.defaultof
val runClientServer : clientF:(Client -> Indexed<Client,'a,Bottom,'T>) -> serverF:(Server -> Indexed<Server,'a,Bottom,'b>) -> 'T (requires 'a :> Index)

Full name: Script.runClientServer
val clientF : (Client -> Indexed<Client,#Index,Bottom,'T>)
val serverF : (Server -> Indexed<Server,#Index,Bottom,'b>)
val attest : (unit -> unit)
static member Indexed.Match : f:Indexed<'a,'I1,'I2,'b> -> g:Indexed<'c,'I1,'I2,'d> -> unit (requires 'I1 :> Index and 'I2 :> Index)
val session : Session
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
property Session.Client: Client
type obj = System.Object

Full name: Microsoft.FSharp.Core.obj
property Session.Server: Server
Multiple items
type Async
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken

Full name: Microsoft.FSharp.Control.Async

--------------------
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
val x : obj []
val clientWorkflow : i:int -> j:int -> self:Client -> Indexed<Client,Op<Send,int,Op<Send,int,Op<Offer,Branch<Op<Receive,string,'a>,Op<Receive,'b,'a>>>>>,'a,'b option> (requires 'a :> Index)

Full name: Script.clientWorkflow
val j : int
val self : Client
member Client.Send : x:'T -> Indexed<Client,Op<Send,'T,'h>,'h,unit> (requires 'h :> Index)
val result : bool
member Client.Offer : unit -> Indexed<Client,Op<Offer,'f>,'f,bool> (requires 'f :> Index)
static member Branch.B1Of2 : unit -> Indexed<'Tag,Branch<'B1,#Index>,'B1,unit> (requires 'B1 :> Index)
val msg : string
member Client.Receive : unit -> Indexed<Client,Op<Receive,'T,'g>,'g,'T> (requires 'g :> Index)
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
union case Option.None: Option<'T>
static member Branch.B2Of2 : unit -> Indexed<'Tag,Branch<#Index,'B2>,'B2,unit> (requires 'B2 :> Index)
val x : 'b
union case Option.Some: Value: 'T -> Option<'T>
val serverWorkflow : self:Server -> Indexed<Server,Op<Send,int,Op<Send,int,Op<Offer,Branch<Op<Receive,string,'a>,Op<Receive,int,'a>>>>>,'a,unit> (requires 'a :> Index)

Full name: Script.serverWorkflow
val self : Server
member Server.Receive : unit -> Indexed<Server,Op<Send,'T,'c>,'c,'T> (requires 'c :> Index)
member Server.Choose : value:bool -> Indexed<Server,Op<Offer,'b>,'b,unit> (requires 'b :> Index)
member Server.Send : x:'T -> Indexed<Server,Op<Receive,'T,'d>,'d,unit> (requires 'd :> Index)
namespace System.IO
type Serialize

Full name: Script.Serialize
type Deserialize

Full name: Script.Deserialize
type Primitive

Full name: Script.Primitive
val serializer : IndexedBuilder<Serialize>

Full name: Script.serializer
val deserializer : IndexedBuilder<Deserialize>

Full name: Script.deserializer
Multiple items
type Writer =
  new : m:MemoryStream -> Writer
  member Choose1Of2 : unit -> Indexed<Serialize,Op<Choose,Branch<'c,#Index>>,'c,unit> (requires 'c :> Index)
  member Choose2Of2 : unit -> Indexed<Serialize,Op<Choose,Branch<#Index,'b>>,'b,unit> (requires 'b :> Index)
  member Write : x:'T -> Indexed<Serialize,Op<Primitive,'T,'e>,'e,unit> (requires 'e :> Index)

Full name: Script.Writer

--------------------
new : m:MemoryStream -> Writer
val m : MemoryStream
Multiple items
type MemoryStream =
  inherit Stream
  new : unit -> MemoryStream + 6 overloads
  member CanRead : bool
  member CanSeek : bool
  member CanWrite : bool
  member Capacity : int with get, set
  member Flush : unit -> unit
  member GetBuffer : unit -> byte[]
  member Length : int64
  member Position : int64 with get, set
  member Read : buffer:byte[] * offset:int * count:int -> int
  ...

Full name: System.IO.MemoryStream

--------------------
MemoryStream() : unit
MemoryStream(capacity: int) : unit
MemoryStream(buffer: byte []) : unit
MemoryStream(buffer: byte [], writable: bool) : unit
MemoryStream(buffer: byte [], index: int, count: int) : unit
MemoryStream(buffer: byte [], index: int, count: int, writable: bool) : unit
MemoryStream(buffer: byte [], index: int, count: int, writable: bool, publiclyVisible: bool) : unit
property MemoryStream.Position: int64
val bw : BinaryWriter
Multiple items
type BinaryWriter =
  new : output:Stream -> BinaryWriter + 1 overload
  member BaseStream : Stream
  member Close : unit -> unit
  member Dispose : unit -> unit
  member Flush : unit -> unit
  member Seek : offset:int * origin:SeekOrigin -> int64
  member Write : value:bool -> unit + 17 overloads
  static val Null : BinaryWriter

Full name: System.IO.BinaryWriter

--------------------
BinaryWriter(output: Stream) : unit
BinaryWriter(output: Stream, encoding: System.Text.Encoding) : unit
member Writer.Write : x:'T -> Indexed<Serialize,Op<Primitive,'T,'e>,'e,unit> (requires 'e :> Index)

Full name: Script.Writer.Write
val write : (unit -> unit)
val box : value:'T -> obj

Full name: Microsoft.FSharp.Core.Operators.box
val b : bool
BinaryWriter.Write(value: string) : unit
   (+0 other overloads)
BinaryWriter.Write(value: float32) : unit
   (+0 other overloads)
BinaryWriter.Write(value: uint64) : unit
   (+0 other overloads)
BinaryWriter.Write(value: int64) : unit
   (+0 other overloads)
BinaryWriter.Write(value: uint32) : unit
   (+0 other overloads)
BinaryWriter.Write(value: int) : unit
   (+0 other overloads)
BinaryWriter.Write(value: uint16) : unit
   (+0 other overloads)
BinaryWriter.Write(value: int16) : unit
   (+0 other overloads)
BinaryWriter.Write(value: decimal) : unit
   (+0 other overloads)
BinaryWriter.Write(value: float) : unit
   (+0 other overloads)
Multiple items
val float : value:'T -> float (requires member op_Explicit)

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

--------------------
type float = System.Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
val f : float
Multiple items
val string : value:'T -> string

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

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
val s : string
val invalidArg : argumentName:string -> message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.invalidArg
val typeof<'T> : System.Type

Full name: Microsoft.FSharp.Core.Operators.typeof
val __ : Writer
member Writer.Choose1Of2 : unit -> Indexed<Serialize,Op<Choose,Branch<'c,#Index>>,'c,unit> (requires 'c :> Index)

Full name: Script.Writer.Choose1Of2
member Writer.Choose2Of2 : unit -> Indexed<Serialize,Op<Choose,Branch<#Index,'b>>,'b,unit> (requires 'b :> Index)

Full name: Script.Writer.Choose2Of2
Multiple items
type Reader =
  new : m:MemoryStream -> Reader
  member Offer : unit -> Indexed<Deserialize,Op<Choose,'a>,'a,bool> (requires 'a :> Index)
  member Read : unit -> Indexed<Deserialize,Op<Primitive,'T,'b>,'b,'c> (requires 'b :> Index)

Full name: Script.Reader

--------------------
new : m:MemoryStream -> Reader
val br : BinaryReader
Multiple items
type BinaryReader =
  new : input:Stream -> BinaryReader + 1 overload
  member BaseStream : Stream
  member Close : unit -> unit
  member Dispose : unit -> unit
  member PeekChar : unit -> int
  member Read : unit -> int + 2 overloads
  member ReadBoolean : unit -> bool
  member ReadByte : unit -> byte
  member ReadBytes : count:int -> byte[]
  member ReadChar : unit -> char
  ...

Full name: System.IO.BinaryReader

--------------------
BinaryReader(input: Stream) : unit
BinaryReader(input: Stream, encoding: System.Text.Encoding) : unit
member Reader.Read : unit -> Indexed<Deserialize,Op<Primitive,'T,'b>,'b,'c> (requires 'b :> Index)

Full name: Script.Reader.Read
val read : (unit -> 'T)
val t : System.Type
BinaryReader.ReadBoolean() : bool
BinaryReader.ReadInt32() : int
BinaryReader.ReadDouble() : float
BinaryReader.ReadString() : string
val __ : Reader
Multiple items
member Reader.Offer : unit -> Indexed<Deserialize,Op<Choose,'a>,'a,bool> (requires 'a :> Index)

Full name: Script.Reader.Offer

--------------------
type Offer

Full name: Script.Offer
val runSerializationLoop : ser:('T -> Writer -> Indexed<Serialize,'a,Bottom,unit>) -> dser:(Reader -> Indexed<Deserialize,'a,Bottom,'T>) -> x:'T -> 'T (requires 'a :> Index)

Full name: Script.runSerializationLoop
val ser : ('T -> Writer -> Indexed<Serialize,#Index,Bottom,unit>)
val dser : (Reader -> Indexed<Deserialize,#Index,Bottom,'T>)
val serialize : c:Choice<('T * 'U),'S option> -> w:Writer -> Indexed<Serialize,Op<Choose,Branch<Op<Primitive,'T,Op<Primitive,'U,'a>>,Op<Choose,Branch<'a,Op<Primitive,'S,'a>>>>>,'a,unit> (requires 'a :> Index)

Full name: Script.serialize
val c : Choice<('T * 'U),'S option>
Multiple items
type Choice<'T1,'T2> =
  | Choice1Of2 of 'T1
  | Choice2Of2 of 'T2

Full name: Microsoft.FSharp.Core.Choice<_,_>

--------------------
type Choice<'T1,'T2,'T3> =
  | Choice1Of3 of 'T1
  | Choice2Of3 of 'T2
  | Choice3Of3 of 'T3

Full name: Microsoft.FSharp.Core.Choice<_,_,_>

--------------------
type Choice<'T1,'T2,'T3,'T4> =
  | Choice1Of4 of 'T1
  | Choice2Of4 of 'T2
  | Choice3Of4 of 'T3
  | Choice4Of4 of 'T4

Full name: Microsoft.FSharp.Core.Choice<_,_,_,_>

--------------------
type Choice<'T1,'T2,'T3,'T4,'T5> =
  | Choice1Of5 of 'T1
  | Choice2Of5 of 'T2
  | Choice3Of5 of 'T3
  | Choice4Of5 of 'T4
  | Choice5Of5 of 'T5

Full name: Microsoft.FSharp.Core.Choice<_,_,_,_,_>

--------------------
type Choice<'T1,'T2,'T3,'T4,'T5,'T6> =
  | Choice1Of6 of 'T1
  | Choice2Of6 of 'T2
  | Choice3Of6 of 'T3
  | Choice4Of6 of 'T4
  | Choice5Of6 of 'T5
  | Choice6Of6 of 'T6

Full name: Microsoft.FSharp.Core.Choice<_,_,_,_,_,_>

--------------------
type Choice<'T1,'T2,'T3,'T4,'T5,'T6,'T7> =
  | Choice1Of7 of 'T1
  | Choice2Of7 of 'T2
  | Choice3Of7 of 'T3
  | Choice4Of7 of 'T4
  | Choice5Of7 of 'T5
  | Choice6Of7 of 'T6
  | Choice7Of7 of 'T7

Full name: Microsoft.FSharp.Core.Choice<_,_,_,_,_,_,_>
type 'T option = Option<'T>

Full name: Microsoft.FSharp.Core.option<_>
val w : Writer
union case Choice.Choice1Of2: 'T1 -> Choice<'T1,'T2>
val t : 'T
val u : 'U
member Writer.Choose1Of2 : unit -> Indexed<Serialize,Op<Choose,Branch<'c,#Index>>,'c,unit> (requires 'c :> Index)
member Writer.Write : x:'T -> Indexed<Serialize,Op<Primitive,'T,'e>,'e,unit> (requires 'e :> Index)
union case Choice.Choice2Of2: 'T2 -> Choice<'T1,'T2>
val sOpt : 'S option
member Writer.Choose2Of2 : unit -> Indexed<Serialize,Op<Choose,Branch<#Index,'b>>,'b,unit> (requires 'b :> Index)
val s : 'S
val deserialize : r:Reader -> Indexed<Deserialize,Op<Choose,Branch<Op<Primitive,'a,Op<Primitive,'b,'c>>,Op<Choose,Branch<'c,Op<Primitive,'d,'c>>>>>,'c,Choice<('e * 'f),'g option>> (requires 'c :> Index)

Full name: Script.deserialize
val r : Reader
val branch : bool
member Reader.Offer : unit -> Indexed<Deserialize,Op<Choose,'a>,'a,bool> (requires 'a :> Index)
val t : 'e
member Reader.Read : unit -> Indexed<Deserialize,Op<Primitive,'T,'b>,'b,'c> (requires 'b :> Index)
val u : 'f
val s : 'g
val x : Choice<(int * string),int option>

Full name: Script.x
type ReversiblePrimitive =
  {Do: unit -> unit;
   Undo: unit -> unit;}

Full name: Script.ReversiblePrimitive
ReversiblePrimitive.Do: unit -> unit
ReversiblePrimitive.Undo: unit -> unit
val verbose : msg:string -> ReversiblePrimitive

Full name: Script.verbose
type Forward

Full name: Script.Forward
type Reverse

Full name: Script.Reverse
Multiple items
type Forward

Full name: Script.Forward

--------------------
type Forward<'Name> =
  static member Run : f:ReversiblePrimitive -> Indexed<Forward,Op<'Name,'a>,'a,unit> (requires 'a :> Index)

Full name: Script.Forward<_>
static member Forward.Run : f:ReversiblePrimitive -> Indexed<Forward,Op<'Name,'a>,'a,unit> (requires 'a :> Index)

Full name: Script.Forward`1.Run
val f : ReversiblePrimitive
Multiple items
type Reverse

Full name: Script.Reverse

--------------------
type Reverse<'Name> =
  static member Undo : f:ReversiblePrimitive -> Indexed<Reverse,Op<'Name,'a>,'a,unit> (requires 'a :> Index)

Full name: Script.Reverse<_>
static member Reverse.Undo : f:ReversiblePrimitive -> Indexed<Reverse,Op<'Name,'a>,'a,unit> (requires 'a :> Index)

Full name: Script.Reverse`1.Undo
val forward : IndexedBuilder<Forward>

Full name: Script.forward
val reverse : DualIndexedBuilder<Reverse>

Full name: Script.reverse
val isReverseOf : f:Indexed<Reverse,'a,Bottom,'b> -> g:Indexed<Forward,'a,Bottom,'c> -> unit (requires 'a :> Index)

Full name: Script.isReverseOf
val f : Indexed<Reverse,#Index,Bottom,'b>
val g : Indexed<Forward,#Index,Bottom,'c>
type Action1

Full name: Script.Action1
type Action2

Full name: Script.Action2
type Action3

Full name: Script.Action3
type Loop

Full name: Script.Loop
val install : unit -> Indexed<Forward,Op<Action1,Op<Action2,Op<Action3,Iterate<Op<Loop,'a>,Four>>>>,'a,unit> (requires 'a :> Index)

Full name: Script.install
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val uninstall : unit -> Indexed<Reverse,Op<Action1,Op<Action2,Op<Action3,Iterate<Op<Loop,'a>,Four>>>>,'a,unit> (requires 'a :> Index)

Full name: Script.uninstall
val attest : unit -> unit

Full name: Script.attest
Raw view Test code New version

More information

Link:http://fssnip.net/jL
Posted:10 years ago
Author:Eirik Tsarpalis
Tags: indexed monad , session types , serialization , reversible computation