Combining FsCheck Properties in a single Test

You may have a bunch of tests that are very similar, and you don’t want to repeat yourself so many times. In FsCheck you can “and” properties with the .&. operator and label failures with either of the @| or |@ operators. The only problem is the first failing property will trigger all the subsequent labels to write as well. Here’s a little work-around to that situation:

1: 
2: 
3: 
4: 
5: 
6: 
7: 
[<Test>]
let ``returns expected length``() =
    Check.VerboseThrowOnFailure 
        ( (1 = 1) |@ sprintf "1 != 2" 
        .&. (2 = 3) |@ sprintf (if false then "" else "2 != 3")
        .&. (3 = 3) |@ sprintf (if (3 = 3) then "" else "3 != 4") 
        .&. (4 = 5) |@ sprintf (if false then "" else "4 != 5") )

Remember the code to the left of |@ is an FsCheck property, and the similar looking statement to the right is an F# expression returning a bool, so you have to keep these two pieces of code in sync. Other than that hassle, this works and will only print labels from failing properties in your combined test.

val ( returns expected length ) : unit -> unit

Full name: Snippet.( returns expected length )

type Check =
  static member All : config:Config -> unit
  static member All : config:Config * test:Type -> unit
  static member Method : config:Config * methodInfo:MethodInfo * ?target:obj -> unit
  static member One : config:Config * property:’Testable -> unit
  static member One : name:string * config:Config * property:’Testable -> unit
  static member Quick : property:’Testable -> unit
  static member Quick : name:string * property:’Testable -> unit
  static member QuickAll : unit -> unit
  static member QuickAll : test:Type -> unit
  static member QuickThrowOnFailure : property:’Testable -> unit
  …

Full name: FsCheck.Check

static member Check.VerboseThrowOnFailure : property:’Testable -> unit
val sprintf : format:Printf.StringFormat<‘T> -> ‘T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf

Transparent Heterogeneous Parallel Async with F#

Here’s a strikingly transparent solution to performing parallel Async returning heterogeneous types. Take a look for yourself.

(The solution presented here is based on a gist sent to me by Anton Tayanovskyy, Twitter: @t0yv0.)

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
let myInt, myChar, myBool, myString =
    Parallel.Pure (fun w x y z -> (w, x, y, z))
    <*> async { return 1 }
    <*> async { return 'b' }
    <*> async { return true }
    <*> async { return "abc" }
    |> Parallel.Run
    |> Async.RunSynchronously

The custom infix operator clearly maps the parallel operations to the elements of the resulting tuple. That’s it. Done.

The use case I was struggling with involved multiple queries using SqlCommandProvider that the host application could perform in parallel, except SqlCommandProvider returns sequences of records typed to the result of each query, and the Parallel member in Async<'T> requires a consistently typed 'T. Requiring heterogeneously typed responses that the app can perform in parallel is such a common use case I expected a literature search to turn up an appealing solution, but it seemed like authors were ignoring this important case.

You still have to tune it

The project I was working on required 9 asynchronous calls to the SQL Server.1 Sequentially calling out the queries to the server took 438ms, and this is within an online app, so parallelization is clearly desirable. Packaging-up all 9 queries into the heterogeneous parallelizer resulted in…1,816ms!! Not exactly the result I was looking for. What happened?

The application host workstation had a quad-core processor running @3.60 GHz, but SQL Server was running on an old dual-core server running @2.33 GHz. It seems overloading the maximum number of simultaneous processes, four, on the SQL Server results in a bottleneck that is four times as slow as sequentially processing the 9 queries. A little experimenting with different configurations resulted in these timings:

Configuration Time
Parallel 9 1,816 ms
Parallel 6-3 751 ms
Sequential 9 438 ms
Parallel 3-3-3 357 ms
Parallel 4-4-1 278 ms
Parallel 4-5 258 ms

For this hardware configuration the sweet spot appears to be matching or overloading by no more than one the number of processes available on the server 2 and sequentially executing twice. The moral of the story is to tune the number of parallel Asyncs according to the run environment.

Conceivably if you make calls to different hosts there would be no practical upper bound to the number of Asyncs you could parallelize, but this is not true. Parallel<'T> is using the local host’s thread pool, for which there is some overhead for each additional thread. Also you also might do some local housekeeping within each Async<'T>. In my case that would be instantiating the record sequences from SqlCommandProvider into lists or arrays. As you cross over from IO-bound to CPU-bound tasks, you will have to tune to meet the thread pool constraints on the application host.

Under the hood

It’s important to note Parallel is a helper type and the <*> operator provides a facade over the F# standard library implementation of Async.Parallel, which is where the real work of parallel scheduling is taking place.

Let’s take a look at the full implementation of this clever solution.

 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: 
type Parallel<'T> =
    private {
        Compute : Async<obj>[]
        Unpack : obj [] -> int -> 'T
    }

    static member ( <*> ) (f: Parallel<'A -> 'B>, x: Parallel<'A>) : Parallel<'B> =
        {
            Compute = Array.append f.Compute x.Compute
            Unpack = fun xs pos ->
                let fv = f.Unpack xs pos
                let xv = x.Unpack xs (pos + f.Compute.Length)
                fv xv
        }

    static member ( <*> ) (f: Parallel<'A ->' B>, x: Async<'A>) : Parallel<'B> =
        f <*> Parallel.Await(x)

and Parallel =

    static member Run<'T> (p: Parallel<'T>) : Async<'T> =
        async {
            let! results =
                match p.Compute.Length with
                | 0 -> async.Return [|box ()|]
                | 1 -> async { let! r = p.Compute.[0] 
                               return [| r |] }
                | _ -> Async.Parallel p.Compute
            return p.Unpack results 0
        }

    static member Await<'T> (x: Async<'T>) : Parallel<'T> =
        {
            Compute =
                [|
                    async {
                        let! v = x
                        return box v
                    }
                |]
            Unpack = fun xs pos -> unbox xs.[pos]
        }

    static member Pure<'T>(x: 'T) : Parallel<'T> =
        {
            Compute = [||]
            Unpack = fun _ _ -> x
        }

Given the signature of Async.Parallel<'T>, seq<Async<'T>> -> Async<'T []>, the only practical way to execute over heterogeneous types is to box them. The innovation of the Parallel type is to make this easy and flexible. Walking through the code execution, the Pure member takes a fully generic function returning a tuple and returns a Parallel typed by that function. Each subsequent useage of the <*> operator and AsyncBuilder returns a new Parallel with the return type of the builder partially applied to the previous function type until strong types have been fully applied and the resulting Parallel is of type the return required strongly typed tuple.

The following illustrates this process (interspersed comments show the state of the let binding if it had ended there):

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
let test1 () =
    Parallel.Pure (fun x y z -> (x, y, z))
        // unit -> Parallel<('a -> 'b -> 'c -> 'a * 'b * 'c)>

    <*> async { return 1 }
        // unit -> Parallel<('b -> 'c -> int * 'b * 'c)>

    <*> async { return 'b' }
        // unit -> Parallel<('c -> int * char * 'c)>

    <*> async { return true }
        // unit -> Parallel<int * char * bool>

    |> Parallel.Run
        // unit -> Async<int * char * bool>

    |> Async.RunSynchronously
        // unit -> int * char * bool

As you can tell, there is more complexity involved in eventually returning strongly-typed tuple. I suggest stepping through the debugger for a deeper understanding.

Check out the code in F# Snippets and try running it in Tsunami Cloud by clicking "tsunami.io" from the snippet.

Footnotes

[1] I picked a time of minimal network activity for my testing, resulting in very little variance in my test results. In some cases the average actually coincided with the median. Where they differ I split the difference and report that number. I repeated each test 10 times. The workstation acting as app host and SQL Server are on the same sub-net. Of course repeated calls to the same queries resulted in caching on the server.

[2] This was actually the staging environment of a production system. What a dilemma this presents! Tune for the production system with a 24 core server, resulting in terrible responsiveness in the staging environment ("trust me, QA, this will be fast in production"), or add complexity to the code by implementing different tunings for different environments. I did not test with the production server, but my guess is it would be most efficient to perform all 9 queries in parallel.

Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel.Parallel<_>

Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.Parallel.myInt

val myChar : char

Full name: Snippet.Parallel.myChar

val myBool : bool

Full name: Snippet.Parallel.myBool

val myString : string

Full name: Snippet.Parallel.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel.Parallel<_>

Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.Parallel.myInt

val myChar : char

Full name: Snippet.Parallel.myChar

val myBool : bool

Full name: Snippet.Parallel.myBool

val myString : string

Full name: Snippet.Parallel.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel.Parallel<_>

Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.Parallel.myInt

val myChar : char

Full name: Snippet.Parallel.myChar

val myBool : bool

Full name: Snippet.Parallel.myBool

val myString : string

Full name: Snippet.Parallel.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel.Parallel<_>

Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.Parallel.myInt

val myChar : char

Full name: Snippet.Parallel.myChar

val myBool : bool

Full name: Snippet.Parallel.myBool

val myString : string

Full name: Snippet.Parallel.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel.Parallel<_>

Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.Parallel.myInt

val myChar : char

Full name: Snippet.Parallel.myChar

val myBool : bool

Full name: Snippet.Parallel.myBool

val myString : string

Full name: Snippet.Parallel.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel.Parallel<_>

Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.Parallel.myInt

val myChar : char

Full name: Snippet.Parallel.myChar

val myBool : bool

Full name: Snippet.Parallel.myBool

val myString : string

Full name: Snippet.Parallel.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel.Parallel<_>

Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.Parallel.myInt

val myChar : char

Full name: Snippet.Parallel.myChar

val myBool : bool

Full name: Snippet.Parallel.myBool

val myString : string

Full name: Snippet.Parallel.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel.Parallel<_>

Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.Parallel.myInt

val myChar : char

Full name: Snippet.Parallel.myChar

val myBool : bool

Full name: Snippet.Parallel.myBool

val myString : string

Full name: Snippet.Parallel.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel.Parallel<_>

Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.Parallel.myInt

val myChar : char

Full name: Snippet.Parallel.myChar

val myBool : bool

Full name: Snippet.Parallel.myBool

val myString : string

Full name: Snippet.Parallel.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel.Parallel<_>

Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.Parallel.myInt

val myChar : char

Full name: Snippet.Parallel.myChar

val myBool : bool

Full name: Snippet.Parallel.myBool

val myString : string

Full name: Snippet.Parallel.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel.Parallel<_>

Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.Parallel.myInt

val myChar : char

Full name: Snippet.Parallel.myChar

val myBool : bool

Full name: Snippet.Parallel.myBool

val myString : string

Full name: Snippet.Parallel.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel.Parallel<_>

Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.Parallel.myInt

val myChar : char

Full name: Snippet.Parallel.myChar

val myBool : bool

Full name: Snippet.Parallel.myBool

val myString : string

Full name: Snippet.Parallel.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel.Parallel<_>

Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.Parallel.myInt

val myChar : char

Full name: Snippet.Parallel.myChar

val myBool : bool

Full name: Snippet.Parallel.myBool

val myString : string

Full name: Snippet.Parallel.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel.Parallel<_>

Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.Parallel.myInt

val myChar : char

Full name: Snippet.Parallel.myChar

val myBool : bool

Full name: Snippet.Parallel.myBool

val myString : string

Full name: Snippet.Parallel.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel<_>

val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.myInt

val myChar : char

Full name: Snippet.myChar

val myBool : bool

Full name: Snippet.myBool

val myString : string

Full name: Snippet.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
Parallel.Compute: Async<obj> []
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

——————–
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 obj = System.Object

Full name: Microsoft.FSharp.Core.obj

Parallel.Unpack: obj [] -> int -> 'T
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

——————–
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

——————–
type int = int32

Full name: Microsoft.FSharp.Core.int

val f : Parallel<('A -> 'B)>
Multiple items
type Parallel =
  static member Await : x:Async<'T> -> Parallel<'T>
  static member Pure : x:'T -> Parallel<'T>
  static member Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel

——————–
type Parallel<'T> =
  private {Compute: Async<obj> [];
           Unpack: obj [] -> int -> 'T;}
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Parallel<'A> -> Parallel<'B>
  static member ( <*> ) : f:Parallel<('A -> 'B)> * x:Async<'A> -> Parallel<'B>

Full name: Snippet.Parallel<_>

val x : Parallel<'A>
module Array

from Microsoft.FSharp.Collections

val append : array1:'T [] -> array2:'T [] -> 'T []

Full name: Microsoft.FSharp.Collections.Array.append

val xs : obj []
val pos : int
val fv : ('A -> 'B)
Parallel.Unpack: obj [] -> int -> 'A -> 'B
val xv : 'A
Parallel.Unpack: obj [] -> int -> 'A
property System.Array.Length: int
val x : Async<'A>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>
static member Parallel.Run : p:Parallel<'T> -> Async<'T>

Full name: Snippet.Parallel.Run

val p : Parallel<'T>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async

val results : obj []
member AsyncBuilder.Return : value:'T -> Async<'T>
val box : value:'T -> obj

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

val r : obj
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member Parallel.Await : x:Async<'T> -> Parallel<'T>

Full name: Snippet.Parallel.Await

val x : Async<'T>
val v : 'T
val unbox : value:obj -> 'T

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

static member Parallel.Pure : x:'T -> Parallel<'T>

Full name: Snippet.Parallel.Pure

val x : 'T
val myInt : int

Full name: Snippet.myInt

val myChar : char

Full name: Snippet.myChar

val myBool : bool

Full name: Snippet.myBool

val myString : string

Full name: Snippet.myString

static member Parallel.Pure : x:'T -> Parallel<'T>
val w : int
val x : char
val y : bool
val z : string
static member Parallel.Run : p:Parallel<'T> -> Async<'T>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
val test1 : unit -> int * char * bool

Full name: Snippet.test1

val x : int
val y : char
val z : bool

Great Ideas Made Real in F#

I’m honored to have been chosen by Microsoft as a Most Valuable Professional for F#, and the recent 5 days I spent at the annual MVP Summit were thrilling, stimulating, and eye-opening. While I can’t talk about much of what I learned and participated in, I want to pass on some great things that are completely out in the open, yet little known. They are on the cutting edge of philosophical accomplishment, both changing the world, really. And Microsoft Research is implementing these two great ideas with my favourite programming language.

Quantum Computing

The idea of a quantum computer gestated throughout the 1980’s, most famously in a 1981 proposal by Richard Feynman. The early 1990’s saw the discovery of the first quantum computing algorithm (one that could provably do something much faster than any classical algorithm) and by the middle of the decade Shor’s Algorithm became the first quantum algorithm that could do something really interesting (and spawned a whole genre of misinterpretation of quantum computing capabilities in popular journalism).

MSR is at the forefront of quantum computing research with LIQUi|> (pronounced “liquid”), the most advanced platform for quantum computing simulation in the world. There are no universal quantum computers in the world, yet. Until there are, LIQUi|> plays an important role in evaluating quantum computing capabilities, for instance in physical processes (the real intention of Feynman’s original work), and in providing a platform to evaluate academic work in the field. And it is poised to be the world’s first quantum computing development environment as soon as enough qubits can be entangled to build the worlds first quantum computer.

You can learn more about LIQUi|> in this video and accompanying slides.

The Computational Science Trinity

Here’s another idea, the Trinity of Computational Science. Frequently expounded upon by Robert Harper of Carnegie Mellon’s CS department, this is the unity of Type Theory, Proof Theory, and Category Theory. Taking it down a level towards the practical, think of it as Type Systems (strong typing), proving program correctness, and Functional Programming. The Oregon Programming Languages Summer School (sponsored in part by MSR) is dedicated to teaching these foundations to advance research and practical software engineering.

This is another area of leadership by MSR. This time with a derivative language of F# called F* (F Star). This language and others, like Idris, implement dependent types, an extension of type theory beyond the familiar strong typing of F#, where types can depend on functions, but F* takes it to another level. By interfacing to MSR’s Z3 theorem prover, F* effectively unifies the Computational Science Trinity. Functions and types become manifestations of the same thing and directly connect to correctness proof.

You can download F* and/or work through the interactive tutorial and experiment with it online.

FSharpTest: F# VS Test Project Template

Update Nov. 30, 2013: v1.2 adds VS 2013 support.

Update Nov. 10, 2013: v1.1 adds links to documentation (and just realized I forgot link to NUnit docs) and more samples of FsUnit and FsCheck, including stateful testing.

I finally did something about scratching an itch I’ve had for some time, that is to create an F# test project template, and I have released it upon the world as FSharpTest. No more fumbling around installing all the NuGet packages and opening another of my projects to see how to implement model test cases when I want to add a test project to a Visual Studio solution .

The Components

NUnit is my “go to” test framework and FsUnit lets me write test assertions in a more fluent composeable style. FsCheck and Unquote round-out the template with failing test case examples.

This is a first release to get community feedback, so let me know what you think. It occurred to me I don’t have a sample test case of FsUnit at work, and I should have added links to all the included test tool docs in the code comments, something for the next release. I also want to add more FsCheck technique examples including Stateful Testing and include TickSpec, as soon as I become familiar with that tool.

The available F# testing tools are really first class and I hope this makes it easier and faster for people to bring up tests.

Under the Covers

If you want to create your own distributable VS extension you will need to install the Visual Studio SDK. Here is the article on how to create project templates and you will find the template parameters reference helpful as well.

A template is a handy thing, but if you want to share it you need to wrap it in an
installable project template extension by using the VSIX project template. The steps in this article are pretty complete, but I never did find the “Content” section it talks about, and it doesn’t explicitly explain you have to add the template zip file to the project through the “Assets” tab.

Hackit Yurself

You can actually hack-up a VSIX file by changing its file type to “zip” and editing the contents. In fact that’s mostly how I crafted the entire template. Once you create the original template zip just edit the files and add NuGet packages in the root.

Now that you know that secret you can modify this extension to your own liking, but do let me know how you customize it so I can benefit too and consider putting the changes in future releases.

The Great New York F# Expedition of 2013

Halfway through the first day of our walking tour of New York, Paul tweets me while Sue and I are riding the Statten Island Ferry, can I extend my lightning talk to the N.Y. F# meetup on Tuesday evening? OK, it ended up making for a much better presentation. I spent the evening cutting down my Lambda Jam presentation to its essence, which I pretentiously titled “Semantically Coherent Functional Linear Data Structures”. The video is here This is the latest incarnation of the thoughts I’ve been trying to express since this blog post about the unity of linear purely functional data structures providing alternate composeable linear views and their capabilities.

I was followed by Rachel Reese’s excellent presentation on F# Agents.

NY Progressive F# Tutorials

Wendy and the Skills Matter crew put on a really nice conference For the NY Progressive F# Tutorials. This was my first experience with a Skills Matter conference, and it won’t be my last. Their reputation preceeds them, and now I can vouch they put on no-nonsense hands-on learning conferences for real practitioners. It helps that they get the best speakers. Don Syme’s keynote is captured on video, and the rest of the sessions on audio.

Don Syme:Keynote: F# in the Open Source World, Keynote: F# in the Open Source World
Don Syme : 18th Sep 2013
Don Syme:Calling and extending the F# compiler, Calling and extending the F# compiler
Don Syme and Tomas Petricek : 18th Sep 2013
Tomas Petricek:FCell: Numerical Development in Excel w/ F#, FCell: Numerical Development in Excel
Tomas Petricek and Adam Mlocek : 18th Sep 2013
Rachel  Reese:Try F# from Zero to Data Science, Try F# from Zero to Data Science
Rachel Reese and Phil Trelford : 18th Sep 2013
Chris Marinos:The F# Koans: An Interactive Way to Learn F# Through Testing, F# Koans: An Interactive Way to Learn
Chris Marinos : 18th Sep 2013
Miguel de Icaza:Keynote: F# Beyond Windows, Keynote: F# Beyond Windows
Miguel de Icaza : 18th Sep 2013
Richard Minerich:Graph Man Contest, Graph Man Contest
Richard Minerich and Paulmichael Blasucci : 18th Sep 2013
Phil Trelford:Machine Learning with F#, Machine Learning with F#
Phil Trelford and Mathias Brandewinder : 18th Sep 2013
Dmitry Mozorov:Code Quotations: Code-as-Data for F#, Code Quotations: Code-as-Data for F#
Dmitry Mozorov and Jack Pappas : 18th Sep 2013
Phil Trelford:Pac-Man Kata, Pac-Man Kata
Phil Trelford and Mathias Brandewinder : 18th Sep 2013

The finale of the conference was Tyler Smith mopping the floor with me in the Pac Man AI programming competition, a group photo,

NYC Progressive F# Tutorials 2013 group

and dinner.

NYC Progressive F# Tutorials 2013 dinner

The F# conversations lasted until late in the night, I met some more of the international F# set, and once again the F# community was friendly, inclusive, and interested in progressing everyone’s skills and the state of the art.

After the F#

I was kindly invited to see the keynote of the next day’s conference, “Agile Testing & BDD Exchange”, by Gojko Adzic. If you have any interest at all in testing or user experience, I highly recommend this keynote.

Then I was off to the simultaneous Global GameCraft event in the Dumbo Spot annex to Dumbo Loft hosted by Andrea and Phil, where Phil Trelford gave me a personal tutorial on TickSpec, and I could take the time to work up a draft of this article.

Great Lakes Functional Programming Conference and more

I want to give a plug for the upcoming Great Lakes Functional Programming Conference in Detroit, MI on November 9. If you don’t already know, there is a vibrant functional programming community in Detroit, and kudos to Onorio Catenacci for organizing this.

My next talk is coming up on October 3 in San Francisco to the Bay Area Clojure User Group, “F# for Functional Enthusiasts”. Check it out if you are in the area.

Finally, I just have to pass on this little gem which spilled out of this year’s Strange Loop (darn! missed it again this year).

Gaining FsCheck Fluency through Transparency

You know the most important quality of a good unit test? It has to be incredibly easy to run.
–Onorio Catenacci

Transparency is a close second. It should be obvious what the unit test tests, how it tests it, and when it fails, how it failed and how to reproduce the failure.

FsCheck is the F# implementation of the well known Haskell QuickCheck test combinator library (also available for many other languages). This article demonstrates some of the tools and techniques available in FsCheck not only to make your tests transparent, but also to make FsCheck itself transparent.

(The rest of this article assumes some familiarity with FsCheck. If it is new to you, or you need to brush up on it, FsCheck – Breaking Your Code in New and Exciting Ways is an excellent place to start, and don’t forget the FsCheck documentation )

Choose your Check

The examples in this article come from tests of new functions in FSharpx.Collections.Vector to support Vector<Vector<‘T>>. Let’s look at one test implementing familiar property-based test techniques.

[<Test>]
let WindowedTest() =
    let testWindowed = 
        gen { let! windowLength = Gen.choose(1,5)
              let! source = Arb.generate<List<int>>
              return ((windowSeq windowLength source), (windowLength, source))
        }

    Check.QuickThrowOnFailure   (Prop.forAll  (Arb.fromGen testWindowed)

        (fun (vOfV, (windowLength, source)) -> 
            let outerLength =
                if source.Length = 0 then 1
                else int (Math.Ceiling((float)source.Length/(float)windowLength))
            (outerLength = vOfV.Length &&
                flatten vOfV |> List.ofSeq = source)
            |> Prop.classify (source.Length > 0 && outerLength > 0) "windowLength, outerLength"
            |> Prop.classify (source.Length = 0) "empty"
            |> Prop.collect (windowLength, outerLength)
        )
)

My go to form of FsCheck checking is usually a derivative of Check.Quick, which will check a single property with a default check config. Using the NUnit external runner on a compiled test project, as I usually do, calls for using the Check.QuickThrowOnFailure method, otherwise the runner will leave your test green lit, even though it reports as falsifiable in the Text Output tab

Check a falsification

Let's look at what FsCheck returns upon falsification by slipping a falsification into the property under test:

(outerLength = vOfV.Length && true = false &&

which has the desired result of displaying the generated data that failed:

*** VectorTest.WindowedTest
Falsifiable, after 1 test (0 shrinks) (StdGen (1338874294,295749962)):
(seq [seq [1]], (3, [1]))

This test data came from the return of the gen {...} GenBuilder above. It helps to understand the function under test.

Returns a vector of vectors of given length from the seq. Result may be a jagged vector.
windowSeq : int  -> seq<'T> -> Vector<Vector<'T>>

The first member of the outer tuple of test data is a Vector<Vector<'T>> produced from the parameter data in the second member, a tuple of window length and a source list. (FsCheck does not know about Vector<Vector<'T>>, so it prints it as seq [seq []].)

Classify your input

Once satisfied how FsCheck reports generated data, let's display more information about the range of generated data. Otherwise upon success FsCheck only provides the happy, but otherwise unsatisfying report

*** VectorTest.WindowedTest
Ok, passed 100 tests.

This is where classify and collect come in, allowing us to categorize the input and satisfy ourselves its range is reasonable.

*** VectorTest.WindowedTest
Ok, passed 100 tests.

6% (5, 2), windowLength, outerLength.
6% (5, 1), windowLength, outerLength.
5% (5, 4), windowLength, outerLength.
5% (3, 1), windowLength, outerLength.
4% (5, 1), empty.
4% (4, 1), windowLength, outerLength.
...
1% (1, 11), windowLength, outerLength.
1% (1, 1), windowLength, outerLength.
1% (1, 1), empty.

Verbosely putting it all together

Digging further we can get FsCheck to report the data of every generated test case using Check.Verbose.

*** VectorTest.WindowedTest
0:
(seq [seq []], (4, []))

1:
(seq [seq [-1]; seq [2]; seq [2]; seq [-2]], (1, [-1; 2; 2; -2]))

2:
(seq [seq [1; -3]; seq [-3]], (2, [1; -3; -3]))

3:
(seq [seq []], (5, []))
...

99:
(seq
   [seq [-33; 8; 48]; seq [-77; -31; 10]; seq [50; -75; -29]; seq [12; 58; -69];
    ...],
 (3,
  [-33; 8; 48; -77; -31; 10; 50; -75; -29; 12; 58; -69; -27; 14; 60; -67; -32;
   31; 4; -10; -27; 60; -21; -54; 39; 9; -68; -9; -11; 83; 11; 0; -43; 60; 39;
   80; -41; -1; 41; 82; -39; 1; 43; -83; -37; 4; 44; -81; -35; 6; 46; -79; -33;
   8; 48; -77; -31; 10; -37; -64; -22; 24; 65; -62; -20; 26; 67; -54; -18; 28;
   69; -52; -12; 30; 71; -50; -10; 32; 73; -48; -7; 34; 75; -46]))

Ok, passed 100 tests.

8% (3, 1), windowLength, outerLength.
...

Model-based checking by Command

You now have full command of property-based tests. There is another testing paradigm available within FsCheck, and that is by progressing the object under test from one state to another by means of "commands" and checking the state against an expected model. Kurt Schelfthout shows us how to use this technique at the end of the FSharpx.Collections.Deque tests

I'm not going to fully explain how this technique works, you can read about it here and study the Deque and Vector test examples. Instead I want to focus on transparency in stateful testing.

Out of the box a successful test gives us output like this:

*** VectorTest.Grow Vector<Vector<'T>>, check by flatten
Ok, passed 100 tests.

73% long sequnecs (>6 commands).
20% short sequences (between 1-6 commands).
1% trivial.

FsCheck.Commands.asProperty already provides statistics on the range of our generated tests, but the range is over something generated like this:

let ``Grow, check by flatten`` = 
    [conjInner1Elem(checkFlatten); conjInnerEmpty(checkFlatten); appendInnerMulti(checkFlatten)]

[<Test>]
let ``Grow Vector&lt;Vector&lt;'T>>, check by flatten``() =
    Check.QuickThrowOnFailure (asProperty (specVofV ``Grow, check by flatten``))

The sequences referred to in the output are sequences of generated commands, each potentially altering the previous state of an object under test. This opens the possibilities of

1) using commands as primitives in generating objects under test, and

2) testing multiple features in a single test.

I took advantage of both these possibilities to test the remaining new functions for Vector<Vector<'T>>.

Commands verbosely

So what do generated tests look like? For that, let's turn again to Check.Verbose

*** VectorTest.Grow Vector<Vector<'T>>, check by flatten
0:
[conjInner1Elem: elem = 2; conjInner1Elem: elem = -1]

1:
[conjInner1Elem: elem = 1; conjInnerEmpty; conjInnerEmpty]

2:
[conjInnerEmpty]

3:
[]

4:
[conjInnerEmpty; conjInner1Elem: elem = 0;
 appendInnerMulti: elems = [-6; -2; 5; 6; -3; -2; 5];
 appendInnerMulti: elems = [-2; 5; 6]; appendInnerMulti: elems = [-6; 1; -5];
 conjInnerEmpty]
 ...
Ok, passed 100 tests.

75% long sequnecs (>6 commands).
16% short sequences (between 1-6 commands).
4% trivial.

It is necessary to override ToString() in the commands you write to provide as much information as necessary, otherwise the record of test generations will be considerably less informative:

*** VectorTest.Grow Vector>, check by flatten
0:
[conjInner1Elem; conjInner1Elem]
1:
[conjInner1Elem; conjInnerEmpty]

2:
[conjInnerEmpty]

3:
[]

4:
[conjInnerEmpty; conjInner1Elem; appendInnerMulti;
 appendInnerMult; appendInnerMult; conjInnerEmpty]
 ...

Falsified command

So what output will a falsified command return? For this we will plant a little time-bomb, in order to make it interesting. The Pre member will prevent execution of this command until the other commands have generated an object of sufficient length. Then changing the Post member, where the check is performed to not will cause falsification.

let conjInnerEmpty check = 
    Gen.constant <|
        { new ICommand<Vector2Actual,VectorModel>() with
            member x.RunActual c = c |> conj empty
            member x.RunModel m = m
            member x.Pre m = (length m) > 0
            member x.Post (c,m) = not (check (c,m))
            override x.ToString() = sprintf "conjInnerEmpty"}

Resulting in this falsification output:

VectorTest.Grow Vector<Vector<'T>>, check by flatten:
System.Exception : Falsifiable, after 6 tests (2 shrinks) (StdGen (1351373830,295750028)):
[appendInnerMulti: elems = [0; -4; 0; -3]; conjInnerEmpty]

Conclusion

All-in-all, FsCheck is a powerful tool for unit test generation that provides full visibility into generation, execution, and repeatability. All of the practices I've outlined, verbose checking, classifying and collecting, and intentional falsification, are good exercises to run through every time you write a new test.

Lambda Jam F# Bibliography

Bibliography for my talk “Functional Linear Data Structures in F#” at Lambda Jam 2013.

Slides

Sandboxed demo code and examples from talk

Keynote: The Value of Values

FSharpx.Collections

FSharpx.Collections.Experimental

The Fastest Functional Data Structures Come to F#

Introduction to Microsoft’s IL

Busting 4 Modern Hardware Myths – Are Memory, HDDs, And SSDs Really Random Access?

Telerik’s JustDecompile recommended for IL exploration. Comes with intellisense and plugins extending functionality.

Porting Clojure’s Persistent Data Structures to .NET, part 1

Porting Clojure’s Persistent Data Structures to .NET, part 2

Hash array mapped trie

Solid Collections documentation discussion

A Unified Collection of Purely Functional List-like Data Structures

Purely Functional Stepchildren

Semantics and List-like Data Structures

Comparing F# Queues

Double-ended Queues for F#

Markov chain

Simulating a Markov Chain with F# Sequences

F# data frame library

Breadth-First Numbering: Lessons from a Small Exercise in Algorithm Design

Chicago Lambda Jam: The Must-attend Functional Programming Event

The full Lambda Jam Chicago schedule is now available!

July 8-10, 2013

I’m exited to be a part of this great opportunity for idea sharing across functional language communities. In addition to keynote speakers (Joe Armstrong, Gerald Sussman, and David Nolen), every morning will have nine sessions in three concurrent session paths, but what distinguishes this conference is fully half of each day is devoted to active participation in practical application of a half dozen of today’s most influential functional languages. And I have it on good authority there are going to be ground-breaking hands-on F# sessions you do not want to miss.

Look at the great line-up:

Clojure

The Joy of Flying Robots with Clojure – Carin Meier

Monads and Macros – Chris Houser and Jonathan Claggett

Functional composition – Chris Ford

Lisp and Cancer – Ola Bini

Data, Visibility, and Abstraction – Stuart Sierra

Scala

Functional Async Without the Pain – Jim Powers

Journey to the Heart of the For-Yield – Kelsey Innis

Enabling Microservice Architectures with Scala – Kevin Scaldeferri

Functional I/O in Scala – Nilanjan Raychaudhuri

Erlang

Distributed Programming with Riak Core and Pipe – John Daily

Finite State Machines – Why the fear? – Mahesh Paolini-Subramanya

Addressing Network Congestion in Riak Clusters – Steve Vinoski

Let it Crash: Erlang Fault Tolerance – Tristan Sloughter

F#

Functional Mobile Applications in F# – Adam Granicz

Functional Linear Data Structures in F# – Jack Fox

Clarity of Intent: Three Features of F# Which Lead to Better Code – Paulmichael Blasucci

Haskell

Domain Specific Languages and Towers of Abstraction in Haskell – Gershom Bazerman

QuickCheck: A Silver Bullet for testing? – Joseph Wayne Norton

Simile-Free Monad Recipes – Aditya Siram

Others

Functional Reactive Programming in the Netflix API – Ben Christensen

Protocols, Functors and Type Classes – Creighton Kirkendall

Living in a Post-Functional World – Daniel Spiewak

Copious Data, the “Killer App” for Functional Programming – Dean Wampler

Semantics, clarity, and notation: the benefits of expressions over statements – Tracy Harms

Living in Big Data with Vector Functional Programming – Dave Thomas

Functional Coffeescript for Web UIs – Richard Feldman

Redex: Program Your Semantics – Robby Findler

If that’s not enough, every afternoon we roll up our sleeves with your
choice from 5 incredible workshops ($50/each) or an open jam.

Monday workshops

Try F# from Zero to Data Science – Rachel Reese

The Art of Several Interpreters, Quickly – Dan Friedman, Jason Hemann

Hands-on Intro to Haskell – Bartosz Milewski

Top-down TDD in Clojure – Brian Marick

The Seductions of Scala – Dean Wampler

Tuesday workshops

F# on the Web – Ryan Riley and Daniel Mohl

Program Transformations – William Byrd, Nada Amin

Uses Lenses, Folds and Traversals – Edward Kmett

Functional Web Development with Clojure – Clinton N. Driesbach

Building Applications in Erlang – Garrett Smith

Wednesday workshops

Installed to Productive in Julia – Leah Hanson

Macros! – Drew Colthorp

Compilers from Scratch – Daniel Feltey

Functional Web Applications with
Webmachine
– Sean Cribbs, Chris Meiklejohn

Introduction to Summingbird – Sam Ritchie

Come Join the Functional Programming Event

Registration for Lambda Jam Chicago is
now open. Tickets are $400 for regular admission and $50 per workshop.
Register now!

Sponsorships available!

If your company is interested in hiring functional programmers, please
consider sponsoring Lambda Jam – the
sponsorship prospectus is available.

The Fastest Functional Data Structures Come to F#

I wasn’t expecting it, but there have been some breakthroughs in available functional data structures for F#. I’m talking about speed and versatility, and as always, composability. Now available in FSharpx.Collections.Experimental (and on NuGet) is by far the fastest linear functional data structure (for what it does), FlatList. It’s been available as an internal type for some time as part of the OS F# compiler code. Now for the first time it’s available as a stand-alone type in a component library with intellisense documentation.

It’s implemented as a struct and uses an array as internal storage, so it is just blazing fast (as fast as an array) at what it does best:

Item get

ofSeq

IEnumerable

rev

…and almost all of the array module members (plus some).

What it’s not so fast at (like array) is append. So it’s best loaded from an IEnumerable object rather than built up one element at a time.

Try it out, and post any feedback to the FSharpx GitHub issues. After sufficient beta testing we will graduate it to the FSharpx.Collections namespace.

More to come

I don’t want to steal his thunder, but there is someone quietly working on some more functional data structures that I hope to see soon in FSharspx.

First there’s a performance improvement to the already fast FSharpx.Collections.Vector (actually a new implementation). The speed increases I’m talking about are in the range of 2:1 to 5:1. And a wider range of module function bindings. Very cool.

Next there’s a unique and very versatile functional structure that does about anything you would ever want from a linear structure. I already have some plans for this one.

I’ve already had my hands on these two. They are real. He’s also working on at least one non-linear functional structure I have not evaluated yet, but based on past performance I have high expectations.

F#: Already Engineered for Testability

Reading the re-engineering for testability literature and sitting in on presentations on the topic reveals two interesting points. First, only a small minority of developers currently work on applications that have adequate testability built in, and second (and even more interesting) engineering OO applications for testability is a challenging proposition that consumes much of the time of the best people on the project.

OO/imperative computer languages have no inherent qualities that make applications testable. Building in testability requires adhering to conventions: methods that only do one “thing”, at most one side effect per method (and preferably none), no global variables, dependency injection, inversion of control, and so forth. Dependency injection and inversion of control insert their own kind of complexity into the application, and the first three practices can only be enforced by adhering to conventions, but are built-in features of functional language development.

C# code in.NET development for testability starts looking a lot like F#, but looks can be deceiving. In large OO systems C# testability involves thousands of methods held together by careful planning, developer education, an IoC container, and a mocking library, but ultimately it is all held together by relying on the humans writing code working within the conventions of the testability design. Maybe there are even more layers of software and process complexity to assure programmers adhere to the conventions.

So why not build your app in F# to begin with and let the F# compiler enforce testability? In F# functional development pretty much everything is already a function (either a let binding or member binding of a type) or computation expression. If you are re-engineering for testability, instead of incrementally migrating processes to re-engineered OO code written (by convention) to mimic functional code, try incrementally migrating to an F# project with compiler-enforced testability.

Exploiting the built-in testability of F# has been largely overlooked. Perhaps the built-in correctness of functional F# makes testability appear less significant in comparison to the other advantages it has to offer. While much work has been done in developing F# testing tools, much of it has focused on using F# as the test-build language for the other .NET languages. That is very useful, but F# testability spans the unit-integration-regression testing continuum. Let’s go straight to the heart of the matter and advance tools that exploit F#’s testability.

Here’s a place to start: create a Visual Studio add-in to generate function test stubs. I like NUnit and FsUnit so I’m working them into the design. I’ve also come to prefer fsi signature files as the means of exposing API to other files and the public, but currently you either have to hand build the signature file or use the --sig compile option. There needs to be a way to conveniently generate, properly place, and maintain signature files from within the IDE.

Once you have good signature file maintenance it opens up the next possibility, a “shadow” project containing your core project’s code files, but not the signature files. Why would you want to do this? To reference the shadow project in your test project so it has access to all function bindings, not just the ones exposed by the signature file. (There is likely a more clever way to accomplish the same thing, probably incorporating reflection, but this method follows the principle of least astonishment.)

Of course I’m thinking the shadow project and test project should have as much automated maintenance as possible built it. Stub test methods should be built for every let and member binding, and it should have a mechanism for remembering an exclude list of test methods you choose not to implement, so when you add new bindings you can “update” the test project with new stubs and not recreate the ones you don’t want.

Naming standards are important to get right from the beginning, and coherent test naming is definitely an area for more R&D! (But that would be a whole nother article, if not a book.) To begin with, I would like at least one of the available standards to implement the default stub names to be “[let module name (.) binding name | type name (.) member name] : test 1”. It’s easy to manually change “test 1″ to something more descriptive, if desired. The system should maintain the test methods in sorted order in keeping with the external NUnit test runner.

The stub code should consist of two FsUnit equality statements, one stubbing the function result to assert equality with default values (zero length string, zero, false, etc, and higher order types built from default values), and a second equality asserting true |> should equal false. (The second assert ensures the developer does something useful with the stub or removes it.)

 1: module NUnitFsUnitLibTest.MyLibTest
 2: 
 3: open System
 4: open NUnit.Framework
 5: open FsUnit
 6: open MyProject
 7: open MyProject.MyLib
 8: 
 9: [<Test>]
10: let ``MyLib.addToMyType: Test 1``() =
11:     addToMyType (MyType(0, "", false)) 
12:     |> should equal (MyType(0, "", false))
13:     true |> should equal false
14: 
15: let myType = MyType(0, "", false)
16: 
17: [<Test>]
18: let ``MyType.BoolMember: Test 1``() =
19:     myType.BoolMember |> should equal false
20:     true |> should equal false
21: 
22: [<Test>]
23: let ``MyType.IntMember: Test 1``() =
24:     myType.IntMember |> should equal 0
25:     true |> should equal false
26: 
27: [<Test>]
28: let ``MyType.StringMember: Test 1``() =
29:     myType.StringMember |> should equal ""
30:     true |> should equal false

This is just a starting point for exploiting F# testability. I’m sure more sophisticated test generation systems can (and should!) follow on. Perhaps inferring and generating stubs for edge cases or generating FsCheck stubs.

Testability is a huge hook to promoting F# as a general purpose language. This is an area project managers and enterprise executives can get interested in. What is a better allocation of their expensive programmer resources? Learning and maintaining um-teen design patterns all held together by convention or writing naturally maintainable and testable code from the beginning?

Those tending more towards functional puritanism should also find automating functional test code generation interesting. Because of inherent correctness, the immediate return of finding more bugs faster is not as great as it would be for OO/imperative languages, but near-ready-made regression unit tests really make the testability built-in and goes a long way in protecting against software fragility.

namespace MyProjectTest

module MyLibTest

from MyProjectTest

namespace System
namespace NUnit
namespace NUnit.Framework
module FsUnit
namespace MyProject

module MyLib

from MyProject

Multiple items
type TestAttribute =
  inherit Attribute
  new : unit -> TestAttribute
  member Description : string with get, set

Full name: NUnit.Framework.TestAttribute

——————–
TestAttribute() : unit

val addToMyType : x:MyType -> MyType

Full name: MyProject.MyLib.addToMyType

Multiple items
type MyType =
  new : myInt:int * myString:string * myBool:bool -> MyType
  member BoolMember : bool
  member IntMember : int
  member StringMember : string

Full name: MyProject.MyType

——————–
new : myInt:int * myString:string * myBool:bool -> MyType

val should : f:('a -> #Constraints.Constraint) -> x:'a -> y:obj -> unit

Full name: FsUnit.should

val equal : x:'a -> Constraints.EqualConstraint

Full name: FsUnit.equal

val myType : MyType

Full name: MyProjectTest.MyLibTest.myType

property MyType.BoolMember: bool
property MyType.IntMember: int
property MyType.StringMember: string