namespace System
namespace System.Net
val lookupName : id:int -> string option
Full name: Index.lookupName
val id : int
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
union case Option.Some: Value: 'T -> Option<'T>
val lookupAge : id:int -> int option
Full name: Index.lookupAge
Multiple items
type MaybeBuilder =
new : unit -> MaybeBuilder
member Bind : input:'a option * f:('a -> 'b option) -> 'b option
member Return : x:'c -> 'c option
Full name: Index.MaybeBuilder
--------------------
new : unit -> MaybeBuilder
val this : MaybeBuilder
member MaybeBuilder.Return : x:'c -> 'c option
Full name: Index.MaybeBuilder.Return
val x : 'c
member MaybeBuilder.Bind : input:'a option * f:('a -> 'b option) -> 'b option
Full name: Index.MaybeBuilder.Bind
val input : 'a option
val f : ('a -> 'b option)
union case Option.None: Option<'T>
val x : 'a
val maybe : MaybeBuilder
Full name: Index.maybe
val getCompleteDetails : id:int -> (string * int) option
Full name: Index.getCompleteDetails
val name : string
val age : int
val completeDetails : (string * int) option
Full name: Index.completeDetails
val seqResult : seq<int>
Full name: Index.seqResult
Multiple items
val seq : sequence:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Core.Operators.seq
--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
val fetchAsync : url:string -> Async<string>
Full name: Index.fetchAsync
val url : string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
Multiple items
type Async
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken
Full name: Microsoft.FSharp.Control.Async
--------------------
type Async<'T>
Full name: Microsoft.FSharp.Control.Async<_>
val uri : System.Uri
Multiple items
type Uri =
new : uriString:string -> Uri + 5 overloads
member AbsolutePath : string
member AbsoluteUri : string
member Authority : string
member DnsSafeHost : string
member Equals : comparand:obj -> bool
member Fragment : string
member GetComponents : components:UriComponents * format:UriFormat -> string
member GetHashCode : unit -> int
member GetLeftPart : part:UriPartial -> string
...
Full name: System.Uri
--------------------
System.Uri(uriString: string) : unit
System.Uri(uriString: string, uriKind: System.UriKind) : unit
System.Uri(baseUri: System.Uri, relativeUri: System.Uri) : unit
System.Uri(baseUri: System.Uri, relativeUri: string) : unit
val webClient : WebClient
Multiple items
type WebClient =
inherit Component
new : unit -> WebClient
member BaseAddress : string with get, set
member CachePolicy : RequestCachePolicy with get, set
member CancelAsync : unit -> unit
member Credentials : ICredentials with get, set
member DownloadData : address:string -> byte[] + 1 overload
member DownloadDataAsync : address:Uri -> unit + 1 overload
member DownloadDataTaskAsync : address:string -> Task<byte[]> + 1 overload
member DownloadFile : address:string * fileName:string -> unit + 1 overload
member DownloadFileAsync : address:Uri * fileName:string -> unit + 1 overload
...
Full name: System.Net.WebClient
--------------------
WebClient() : unit
member WebClient.AsyncDownloadString : address:System.Uri -> Async<string>
val readUriAsync : name:string * url:string -> Async<unit>
Full name: Index.readUriAsync
val async : AsyncBuilder
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
val html : string
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
property System.String.Length: int
val ex : exn
property System.Exception.Message: string
module MyOption
from index
Multiple items
module Option
from Microsoft.FSharp.Core
--------------------
type Option<'T> =
| Some of 'T
| None
Full name: index.MyOption.Option<_>
union case Option.Some: 'T -> Option<'T>
val getCompleteDetails2 : id:int -> (string * int) option
Full name: Index.getCompleteDetails2
member MaybeBuilder.Bind : input:'a option * f:('a -> 'b option) -> 'b option
member MaybeBuilder.Return : x:'c -> 'c option
type CExpr =
| Yield of string
| YieldFrom of string
| Combine of CExpr * CExpr
| Delay of CExpr
| Bind of string * CExpr
| Zero
| Return of string
| ReturnFrom of string
| For of string * string
| Run of CExpr
...
Full name: Index.CExpr
union case CExpr.Yield: string -> CExpr
union case CExpr.YieldFrom: string -> CExpr
union case CExpr.Combine: CExpr * CExpr -> CExpr
union case CExpr.Delay: CExpr -> CExpr
union case CExpr.Bind: string * CExpr -> CExpr
union case CExpr.Zero: CExpr
union case CExpr.Return: string -> CExpr
union case CExpr.ReturnFrom: string -> CExpr
union case CExpr.For: string * string -> CExpr
union case CExpr.Run: CExpr -> CExpr
union case CExpr.TryFinally: CExpr * string -> CExpr
union case CExpr.TryWith: CExpr * string -> CExpr
union case CExpr.Using: string * CExpr -> CExpr
union case CExpr.While: string * CExpr -> CExpr
Multiple items
type CEDebugBuilder =
new : unit -> CEDebugBuilder
member Bind : a:'h * f:(unit -> CExpr) -> CExpr
member Combine : a:CExpr * b:CExpr -> CExpr
member Delay : f:(unit -> CExpr) -> CExpr
member For : s:'d * f:'e -> CExpr
member Return : i:'g -> CExpr
member ReturnFrom : i:'f -> CExpr
member TryFinally : f:CExpr * e:'c -> CExpr
member TryWith : expr:CExpr * handler:(Exception -> CExpr) -> CExpr
member Using : v:'b * f:(unit -> CExpr) -> CExpr
...
Full name: Index.CEDebugBuilder
--------------------
new : unit -> CEDebugBuilder
val this : CEDebugBuilder
member CEDebugBuilder.Yield : i:'j -> CExpr
Full name: Index.CEDebugBuilder.Yield
val i : 'j
val sprintf : format:Printf.StringFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
member CEDebugBuilder.YieldFrom : i:'i -> CExpr
Full name: Index.CEDebugBuilder.YieldFrom
val i : 'i
member CEDebugBuilder.Combine : a:CExpr * b:CExpr -> CExpr
Full name: Index.CEDebugBuilder.Combine
val a : CExpr
val b : CExpr
member CEDebugBuilder.Delay : f:(unit -> CExpr) -> CExpr
Full name: Index.CEDebugBuilder.Delay
val f : (unit -> CExpr)
member CEDebugBuilder.Bind : a:'h * f:(unit -> CExpr) -> CExpr
Full name: Index.CEDebugBuilder.Bind
val a : 'h
member CEDebugBuilder.Zero : unit -> CExpr
Full name: Index.CEDebugBuilder.Zero
member CEDebugBuilder.Return : i:'g -> CExpr
Full name: Index.CEDebugBuilder.Return
val i : 'g
member CEDebugBuilder.ReturnFrom : i:'f -> CExpr
Full name: Index.CEDebugBuilder.ReturnFrom
val i : 'f
member CEDebugBuilder.For : s:'d * f:'e -> CExpr
Full name: Index.CEDebugBuilder.For
val s : 'd
val f : 'e
member CEDebugBuilder.TryFinally : f:CExpr * e:'c -> CExpr
Full name: Index.CEDebugBuilder.TryFinally
val f : CExpr
val e : 'c
member CEDebugBuilder.TryWith : expr:CExpr * handler:(System.Exception -> CExpr) -> CExpr
Full name: Index.CEDebugBuilder.TryWith
val expr : CExpr
val handler : (System.Exception -> CExpr)
Multiple items
type Exception =
new : unit -> Exception + 2 overloads
member Data : IDictionary
member GetBaseException : unit -> Exception
member GetObjectData : info:SerializationInfo * context:StreamingContext -> unit
member GetType : unit -> Type
member HResult : int with get, set
member HelpLink : string with get, set
member InnerException : Exception
member Message : string
member Source : string with get, set
...
Full name: System.Exception
--------------------
System.Exception() : unit
System.Exception(message: string) : unit
System.Exception(message: string, innerException: exn) : unit
member CEDebugBuilder.Using : v:'b * f:(unit -> CExpr) -> CExpr
Full name: Index.CEDebugBuilder.Using
val v : 'b
member CEDebugBuilder.While : v:(unit -> 'a) * f:CExpr -> CExpr
Full name: Index.CEDebugBuilder.While
val v : (unit -> 'a)
val bar : CEDebugBuilder
Full name: Index.bar
Multiple items
type CEDebugBuilderNoDelay =
new : unit -> CEDebugBuilderNoDelay
member Bind : a:'h * f:(unit -> CExpr) -> CExpr
member Combine : a:CExpr * b:CExpr -> CExpr
member For : s:'d * f:'e -> CExpr
member Return : i:'g -> CExpr
member ReturnFrom : i:'f -> CExpr
member TryFinally : f:CExpr * e:'c -> CExpr
member TryWith : expr:CExpr * handler:(Exception -> CExpr) -> CExpr
member Using : v:'b * f:(unit -> CExpr) -> CExpr
member While : v:(unit -> 'a) * f:CExpr -> CExpr
...
Full name: Index.CEDebugBuilderNoDelay
--------------------
new : unit -> CEDebugBuilderNoDelay
val this : CEDebugBuilderNoDelay
member CEDebugBuilderNoDelay.Yield : i:'j -> CExpr
Full name: Index.CEDebugBuilderNoDelay.Yield
member CEDebugBuilderNoDelay.YieldFrom : i:'i -> CExpr
Full name: Index.CEDebugBuilderNoDelay.YieldFrom
member CEDebugBuilderNoDelay.Combine : a:CExpr * b:CExpr -> CExpr
Full name: Index.CEDebugBuilderNoDelay.Combine
member CEDebugBuilderNoDelay.Bind : a:'h * f:(unit -> CExpr) -> CExpr
Full name: Index.CEDebugBuilderNoDelay.Bind
member CEDebugBuilderNoDelay.Zero : unit -> CExpr
Full name: Index.CEDebugBuilderNoDelay.Zero
member CEDebugBuilderNoDelay.Return : i:'g -> CExpr
Full name: Index.CEDebugBuilderNoDelay.Return
member CEDebugBuilderNoDelay.ReturnFrom : i:'f -> CExpr
Full name: Index.CEDebugBuilderNoDelay.ReturnFrom
member CEDebugBuilderNoDelay.For : s:'d * f:'e -> CExpr
Full name: Index.CEDebugBuilderNoDelay.For
member CEDebugBuilderNoDelay.TryFinally : f:CExpr * e:'c -> CExpr
Full name: Index.CEDebugBuilderNoDelay.TryFinally
member CEDebugBuilderNoDelay.TryWith : expr:CExpr * handler:(System.Exception -> CExpr) -> CExpr
Full name: Index.CEDebugBuilderNoDelay.TryWith
member CEDebugBuilderNoDelay.Using : v:'b * f:(unit -> CExpr) -> CExpr
Full name: Index.CEDebugBuilderNoDelay.Using
member CEDebugBuilderNoDelay.While : v:(unit -> 'a) * f:CExpr -> CExpr
Full name: Index.CEDebugBuilderNoDelay.While
val foo : CEDebugBuilderNoDelay
Full name: Index.foo
member CEDebugBuilderNoDelay.Yield : i:'j -> CExpr
member CEDebugBuilderNoDelay.YieldFrom : i:'i -> CExpr
member CEDebugBuilderNoDelay.Return : i:'g -> CExpr
member CEDebugBuilderNoDelay.ReturnFrom : i:'f -> CExpr
member CEDebugBuilderNoDelay.Zero : unit -> CExpr
val a : unit
member CEDebugBuilderNoDelay.Using : v:'b * f:(unit -> CExpr) -> CExpr
member CEDebugBuilderNoDelay.Bind : a:'h * f:(unit -> CExpr) -> CExpr
val printf : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printf
member CEDebugBuilder.Delay : f:(unit -> CExpr) -> CExpr
member CEDebugBuilder.Combine : a:CExpr * b:CExpr -> CExpr
member CEDebugBuilder.Return : i:'g -> CExpr
val x : obj
member CEDebugBuilder.For : s:'d * f:'e -> CExpr
member CEDebugBuilder.While : v:(unit -> 'a) * f:CExpr -> CExpr
member CEDebugBuilder.TryFinally : f:CExpr * e:'c -> CExpr
Multiple items
type DivideByZeroException =
inherit ArithmeticException
new : unit -> DivideByZeroException + 2 overloads
Full name: System.DivideByZeroException
--------------------
System.DivideByZeroException() : unit
System.DivideByZeroException(message: string) : unit
System.DivideByZeroException(message: string, innerException: exn) : unit
val e : System.DivideByZeroException
member CEDebugBuilder.TryWith : expr:CExpr * handler:(System.Exception -> CExpr) -> CExpr
val e : System.Exception
Multiple items
val exn : System.Exception
--------------------
type exn = System.Exception
Full name: Microsoft.FSharp.Core.exn
val reraise : unit -> 'T
Full name: Microsoft.FSharp.Core.Operators.reraise
val getPage : n:int -> Async<seq<int>>
Full name: Index.getPage
val n : int
val raise : exn:System.Exception -> 'T
Full name: Microsoft.FSharp.Core.Operators.raise
Multiple items
type NotImplementedException =
inherit SystemException
new : unit -> NotImplementedException + 2 overloads
Full name: System.NotImplementedException
--------------------
System.NotImplementedException() : unit
System.NotImplementedException(message: string) : unit
System.NotImplementedException(message: string, inner: exn) : unit
val getPage : n:int -> Async<seq<int>>
Full name: index.MyOption.getPage
val getAllPagesSeq : seq<int>
Full name: Index.getAllPagesSeq
val loop : (int -> seq<int>)
val results : seq<int>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
module Seq
from Microsoft.FSharp.Collections
val empty<'T> : seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.empty
val getAllPagesAsync : Async<seq<int>>
Full name: Index.getAllPagesAsync
val loop : (int -> seq<int> -> Async<seq<int>>)
val acc : seq<int>
val append : source1:seq<'T> -> source2:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.append
type AsyncSeq<'T> = Async<AsyncSeqInner<'T>>
Full name: Index.AsyncSeq<_>
type AsyncSeqInner<'T> =
internal | Nil
| Cons of 'T * AsyncSeq<'T>
Full name: Index.AsyncSeqInner<_>
union case AsyncSeqInner.Nil: AsyncSeqInner<'T>
union case AsyncSeqInner.Cons: 'T * AsyncSeq<'T> -> AsyncSeqInner<'T>
Multiple items
type GeneralizableValueAttribute =
inherit Attribute
new : unit -> GeneralizableValueAttribute
Full name: Microsoft.FSharp.Core.GeneralizableValueAttribute
--------------------
new : unit -> GeneralizableValueAttribute
val empty<'T> : AsyncSeq<'T>
Full name: Index.empty
val singleton : v:'T -> AsyncSeq<'T>
Full name: Index.singleton
val v : 'T
val append : seq1:AsyncSeq<'T> -> seq2:AsyncSeq<'T> -> AsyncSeq<'T>
Full name: Index.append
val seq1 : AsyncSeq<'T>
val seq2 : AsyncSeq<'T>
val v1 : AsyncSeqInner<'T>
val h : 'T
val t : AsyncSeq<'T>
val toAsyncSeq : xs:seq<'a> -> AsyncSeq<'a>
Full name: Index.toAsyncSeq
val xs : seq<'a>
val head : source:seq<'T> -> 'T
Full name: Microsoft.FSharp.Collections.Seq.head
val skip : count:int -> source:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.skip
Multiple items
type AsyncSeqBuilder =
new : unit -> AsyncSeqBuilder
member Bind : inp:Async<'b> * body:('b -> Async<'c>) -> Async<'c>
member Combine : seq1:AsyncSeq<'d> * seq2:AsyncSeq<'d> -> AsyncSeq<'d>
member Delay : f:(unit -> AsyncSeq<'T>) -> Async<AsyncSeqInner<'T>>
member For : seq:seq<'T> * action:('T -> AsyncSeq<'TResult>) -> Async<AsyncSeqInner<'TResult>>
member For : seq:AsyncSeq<'T> * action:('T -> AsyncSeq<'TResult>) -> AsyncSeq<'TResult>
member TryFinally : body:AsyncSeq<'T> * compensation:(unit -> unit) -> Async<AsyncSeqInner<'T>>
member While : gd:(unit -> bool) * seq:AsyncSeq<'T> -> AsyncSeq<'T>
member Yield : v:'e -> AsyncSeq<'e>
member YieldFrom : s:seq<'a> -> AsyncSeq<'a>
...
Full name: Index.AsyncSeqBuilder
--------------------
new : unit -> AsyncSeqBuilder
val x : AsyncSeqBuilder
member AsyncSeqBuilder.Yield : v:'e -> AsyncSeq<'e>
Full name: Index.AsyncSeqBuilder.Yield
val v : 'e
member AsyncSeqBuilder.YieldFrom : s:seq<'a> -> AsyncSeq<'a>
Full name: Index.AsyncSeqBuilder.YieldFrom
val s : seq<'a>
member AsyncSeqBuilder.YieldFrom : s:AsyncSeq<'a> -> AsyncSeq<'a>
Full name: Index.AsyncSeqBuilder.YieldFrom
val s : AsyncSeq<'a>
member AsyncSeqBuilder.Combine : seq1:AsyncSeq<'d> * seq2:AsyncSeq<'d> -> AsyncSeq<'d>
Full name: Index.AsyncSeqBuilder.Combine
val seq1 : AsyncSeq<'d>
val seq2 : AsyncSeq<'d>
member AsyncSeqBuilder.Bind : inp:Async<'b> * body:('b -> Async<'c>) -> Async<'c>
Full name: Index.AsyncSeqBuilder.Bind
val inp : Async<'b>
val body : ('b -> Async<'c>)
member AsyncBuilder.Bind : computation:Async<'T> * binder:('T -> Async<'U>) -> Async<'U>
member AsyncSeqBuilder.Delay : f:(unit -> AsyncSeq<'T>) -> Async<AsyncSeqInner<'T>>
Full name: Index.AsyncSeqBuilder.Delay
val f : (unit -> AsyncSeq<'T>)
type unit = Unit
Full name: Microsoft.FSharp.Core.unit
member AsyncBuilder.Delay : generator:(unit -> Async<'T>) -> Async<'T>
member AsyncSeqBuilder.Zero : unit -> AsyncSeq<'a>
Full name: Index.AsyncSeqBuilder.Zero
val asyncSeq : AsyncSeqBuilder
Full name: Index.asyncSeq
val internal tryNext : input:AsyncSeq<'a> -> Async<Choice<AsyncSeqInner<'a>,exn>>
Full name: Index.tryNext
Tries to get the next element of an asynchronous sequence
and returns either the value or an exception
val input : AsyncSeq<'a>
val v : AsyncSeqInner<'a>
union case Choice.Choice1Of2: 'T1 -> Choice<'T1,'T2>
val e : exn
union case Choice.Choice2Of2: 'T2 -> Choice<'T1,'T2>
val internal tryFinally : input:AsyncSeq<'T> -> compensation:(unit -> unit) -> Async<AsyncSeqInner<'T>>
Full name: Index.tryFinally
Implements the 'TryFinally' functionality for computation builder
val input : AsyncSeq<'T>
val compensation : (unit -> unit)
val v : Choice<AsyncSeqInner<'T>,exn>
val collect : f:('T -> AsyncSeq<'TResult>) -> input:AsyncSeq<'T> -> AsyncSeq<'TResult>
Full name: Index.collect
val f : ('T -> AsyncSeq<'TResult>)
val v : AsyncSeqInner<'T>
member AsyncSeqBuilder.While : gd:(unit -> bool) * seq:AsyncSeq<'T> -> AsyncSeq<'T>
Full name: Index.AsyncSeqBuilder.While
val gd : (unit -> bool)
Multiple items
val seq : AsyncSeq<'T>
--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
member AsyncSeqBuilder.Combine : seq1:AsyncSeq<'d> * seq2:AsyncSeq<'d> -> AsyncSeq<'d>
member AsyncSeqBuilder.Delay : f:(unit -> AsyncSeq<'T>) -> Async<AsyncSeqInner<'T>>
member AsyncSeqBuilder.While : gd:(unit -> bool) * seq:AsyncSeq<'T> -> AsyncSeq<'T>
member AsyncSeqBuilder.Zero : unit -> AsyncSeq<'a>
member AsyncSeqBuilder.TryFinally : body:AsyncSeq<'T> * compensation:(unit -> unit) -> Async<AsyncSeqInner<'T>>
Full name: Index.AsyncSeqBuilder.TryFinally
val body : AsyncSeq<'T>
member AsyncSeqBuilder.For : seq:seq<'T> * action:('T -> AsyncSeq<'TResult>) -> Async<AsyncSeqInner<'TResult>>
Full name: Index.AsyncSeqBuilder.For
Multiple items
val seq : seq<'T>
--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
val action : ('T -> AsyncSeq<'TResult>)
val enum : System.Collections.Generic.IEnumerator<'T>
System.Collections.Generic.IEnumerable.GetEnumerator() : System.Collections.Generic.IEnumerator<'T>
member AsyncSeqBuilder.TryFinally : body:AsyncSeq<'T> * compensation:(unit -> unit) -> Async<AsyncSeqInner<'T>>
System.Collections.IEnumerator.MoveNext() : bool
property System.Collections.Generic.IEnumerator.Current: 'T
System.IDisposable.Dispose() : unit
member AsyncSeqBuilder.For : seq:AsyncSeq<'T> * action:('T -> AsyncSeq<'TResult>) -> AsyncSeq<'TResult>
Full name: Index.AsyncSeqBuilder.For
val resultLoop : n:int -> Async<AsyncSeqInner<int>>
Full name: Index.resultLoop
val getAllResults : Async<AsyncSeqInner<int>>
Full name: Index.getAllResults
val withPageNumber : Async<AsyncSeqInner<string>>
Full name: Index.withPageNumber
val result : int
val filterAsync : f:('T -> Async<bool>) -> input:AsyncSeq<'T> -> Async<AsyncSeqInner<'T>>
Full name: Index.filterAsync
val f : ('T -> Async<bool>)
val b : bool
type WriteResult =
| WriteSuccess
| WrongExpectedVersion
| WriteError of Exception
Full name: Index.WriteResult
union case WriteResult.WriteSuccess: WriteResult
union case WriteResult.WrongExpectedVersion: WriteResult
union case WriteResult.WriteError: System.Exception -> WriteResult
type Key = string
Full name: Index.Key
type Version = int
Full name: Index.Version
type KeyValueLanguage<'N> =
| ReadValue of Key * ((Version * string) option -> 'N)
| WriteValue of Key * Version * string * (WriteResult -> 'N)
Full name: Index.KeyValueLanguage<_>
union case KeyValueLanguage.ReadValue: Key * ((Version * string) option -> 'N) -> KeyValueLanguage<'N>
type 'T option = Option<'T>
Full name: Microsoft.FSharp.Core.option<_>
union case KeyValueLanguage.WriteValue: Key * Version * string * (WriteResult -> 'N) -> KeyValueLanguage<'N>
type FreeKeyValue<'F,'R> =
| FreeKeyValue of KeyValueLanguage<FreeKeyValue<'F,'R>>
| Pure of 'R
Full name: Index.FreeKeyValue<_,_>
Multiple items
union case FreeKeyValue.FreeKeyValue: KeyValueLanguage<FreeKeyValue<'F,'R>> -> FreeKeyValue<'F,'R>
--------------------
type FreeKeyValue<'F,'R> =
| FreeKeyValue of KeyValueLanguage<FreeKeyValue<'F,'R>>
| Pure of 'R
Full name: Index.FreeKeyValue<_,_>
union case FreeKeyValue.Pure: 'R -> FreeKeyValue<'F,'R>
val fmap : f:('a -> 'b) -> streamWorker:KeyValueLanguage<'a> -> KeyValueLanguage<'b>
Full name: Index.fmap
val f : ('a -> 'b)
val streamWorker : KeyValueLanguage<'a>
val key : Key
val streamRead : ((Version * string) option -> 'a)
val expectedVersion : Version
val value : string
val next : (WriteResult -> 'a)
val bind' : f:('a -> FreeKeyValue<'b,'c>) -> v:FreeKeyValue<'d,'a> -> FreeKeyValue<'b,'c>
Full name: Index.bind'
val f : ('a -> FreeKeyValue<'b,'c>)
val v : FreeKeyValue<'d,'a>
val x : KeyValueLanguage<FreeKeyValue<'d,'a>>
val r : 'a
val result : value:'a -> FreeKeyValue<'b,'a>
Full name: Index.result
val value : 'a
val whileLoop : pred:(unit -> bool) -> body:FreeKeyValue<'a,'b> -> FreeKeyValue<'c,unit>
Full name: Index.whileLoop
val pred : (unit -> bool)
val body : FreeKeyValue<'a,'b>
val delay : func:(unit -> FreeKeyValue<'a,'b>) -> FreeKeyValue<'a,'b>
Full name: Index.delay
val func : (unit -> FreeKeyValue<'a,'b>)
val combine : expr1:FreeKeyValue<'a,unit> -> expr2:FreeKeyValue<'b,'c> -> FreeKeyValue<'b,'c>
Full name: Index.combine
val expr1 : FreeKeyValue<'a,unit>
val expr2 : FreeKeyValue<'b,'c>
val forLoop : collection:seq<'a> -> func:('a -> FreeKeyValue<'b,'c>) -> FreeKeyValue<'d,unit>
Full name: Index.forLoop
val collection : seq<'a>
val func : ('a -> FreeKeyValue<'b,'c>)
val ie : System.Collections.Generic.IEnumerator<'a>
System.Collections.Generic.IEnumerable.GetEnumerator() : System.Collections.Generic.IEnumerator<'a>
property System.Collections.Generic.IEnumerator.Current: 'a
val readValue : key:Key -> FreeKeyValue<'a,(Version * string) option>
Full name: Index.readValue
val writeValue : key:Key -> version:Version -> value:string -> FreeKeyValue<'a,WriteResult>
Full name: Index.writeValue
val version : Version
type InterpeterState<'T> =
| Continue of (Map<string,(int * string)> * FreeKeyValue<obj,'T>)
| Complete of (Map<string,(int * string)> * 'T)
Full name: Index.InterpeterState<_>
union case InterpeterState.Continue: (Map<string,(int * string)> * FreeKeyValue<obj,'T>) -> InterpeterState<'T>
Multiple items
module Map
from Microsoft.FSharp.Collections
--------------------
type Map<'Key,'Value (requires comparison)> =
interface IEnumerable
interface IComparable
interface IEnumerable<KeyValuePair<'Key,'Value>>
interface ICollection<KeyValuePair<'Key,'Value>>
interface IDictionary<'Key,'Value>
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
member Add : key:'Key * value:'Value -> Map<'Key,'Value>
member ContainsKey : key:'Key -> bool
override Equals : obj -> bool
member Remove : key:'Key -> Map<'Key,'Value>
...
Full name: Microsoft.FSharp.Collections.Map<_,_>
--------------------
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
type obj = System.Object
Full name: Microsoft.FSharp.Core.obj
union case InterpeterState.Complete: (Map<string,(int * string)> * 'T) -> InterpeterState<'T>
val runStep : prog:FreeKeyValue<obj,'T> -> dataStore:Map<Key,(Version * string)> -> InterpeterState<'T>
Full name: Index.runStep
val prog : FreeKeyValue<obj,'T>
val dataStore : Map<Key,(Version * string)>
val f : ((Version * string) option -> FreeKeyValue<obj,'T>)
val value : (Version * string) option
val tryFind : key:'Key -> table:Map<'Key,'T> -> 'T option (requires comparison)
Full name: Microsoft.FSharp.Collections.Map.tryFind
val next : FreeKeyValue<obj,'T>
val f : (WriteResult -> FreeKeyValue<obj,'T>)
val currentValue : (Version * string) option
val dataStore' : Map<Key,(Version * string)>
val add : key:'Key -> value:'T -> table:Map<'Key,'T> -> Map<'Key,'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Map.add
val currentVersion : Version
val result : 'T
val interpret : prog:FreeKeyValue<obj,'T> -> dataStore:Map<Key,(Version * string)> -> Map<Key,(Version * string)> * 'T
Full name: Index.interpret
val loop : (InterpeterState<'T> -> Map<string,(int * string)> * 'T)
val state : InterpeterState<'T>
val r : Map<string,(int * string)> * 'T
val state : Map<string,(int * string)>
val p : FreeKeyValue<obj,'T>
Multiple items
type KeyValueBuilder =
new : unit -> KeyValueBuilder
member Bind : inp:FreeKeyValue<'m,'n> * body:('n -> FreeKeyValue<'o,'p>) -> FreeKeyValue<'o,'p>
member Combine : expr1:FreeKeyValue<'j,unit> * expr2:FreeKeyValue<'k,'l> -> FreeKeyValue<'k,'l>
member Delay : func:(unit -> FreeKeyValue<'a,'b>) -> FreeKeyValue<'a,'b>
member For : a:seq<'f> * f:('f -> FreeKeyValue<'g,'h>) -> FreeKeyValue<'i,unit>
member Return : r:'R -> FreeKeyValue<'F,'R>
member ReturnFrom : r:FreeKeyValue<'F,'R> -> FreeKeyValue<'F,'R>
member While : func:(unit -> bool) * body:FreeKeyValue<'c,'d> -> FreeKeyValue<'e,unit>
member Zero : unit -> FreeKeyValue<'q,unit>
Full name: Index.KeyValueBuilder
--------------------
new : unit -> KeyValueBuilder
val x : KeyValueBuilder
member KeyValueBuilder.Zero : unit -> FreeKeyValue<'q,unit>
Full name: Index.KeyValueBuilder.Zero
member KeyValueBuilder.Return : r:'R -> FreeKeyValue<'F,'R>
Full name: Index.KeyValueBuilder.Return
val r : 'R
member KeyValueBuilder.ReturnFrom : r:FreeKeyValue<'F,'R> -> FreeKeyValue<'F,'R>
Full name: Index.KeyValueBuilder.ReturnFrom
val r : FreeKeyValue<'F,'R>
member KeyValueBuilder.Bind : inp:FreeKeyValue<'m,'n> * body:('n -> FreeKeyValue<'o,'p>) -> FreeKeyValue<'o,'p>
Full name: Index.KeyValueBuilder.Bind
val inp : FreeKeyValue<'m,'n>
val body : ('n -> FreeKeyValue<'o,'p>)
member KeyValueBuilder.Combine : expr1:FreeKeyValue<'j,unit> * expr2:FreeKeyValue<'k,'l> -> FreeKeyValue<'k,'l>
Full name: Index.KeyValueBuilder.Combine
val expr1 : FreeKeyValue<'j,unit>
val expr2 : FreeKeyValue<'k,'l>
member KeyValueBuilder.For : a:seq<'f> * f:('f -> FreeKeyValue<'g,'h>) -> FreeKeyValue<'i,unit>
Full name: Index.KeyValueBuilder.For
val a : seq<'f>
val f : ('f -> FreeKeyValue<'g,'h>)
member KeyValueBuilder.While : func:(unit -> bool) * body:FreeKeyValue<'c,'d> -> FreeKeyValue<'e,unit>
Full name: Index.KeyValueBuilder.While
val func : (unit -> bool)
val body : FreeKeyValue<'c,'d>
member KeyValueBuilder.Delay : func:(unit -> FreeKeyValue<'a,'b>) -> FreeKeyValue<'a,'b>
Full name: Index.KeyValueBuilder.Delay
val keyValue : KeyValueBuilder
Full name: Index.keyValue
val appendValue : key:Key -> value:string -> FreeKeyValue<'a,WriteResult>
Full name: Index.appendValue
val current : (Version * string) option
val currentValue : string
val newValue : string
val result : WriteResult
val appendResult : Map<Key,(Version * string)> * WriteResult
Full name: Index.appendResult
val empty<'Key,'T (requires comparison)> : Map<'Key,'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Map.empty
val appendValueWithRetry : key:Key -> value:string -> FreeKeyValue<'a,WriteResult>
Full name: Index.appendValueWithRetry
val loop : (WriteResult -> FreeKeyValue<'b,WriteResult>)
val previousResult : WriteResult
type IRealDataStore =
interface
abstract member Read : Key -> Async<(Version * string) option>
abstract member Write : Key -> Version -> string -> Async<WriteResult>
end
Full name: Index.IRealDataStore
abstract member IRealDataStore.Read : Key -> Async<(Version * string) option>
Full name: Index.IRealDataStore.Read
abstract member IRealDataStore.Write : Key -> Version -> string -> Async<WriteResult>
Full name: Index.IRealDataStore.Write
val realInterpreter : prog:FreeKeyValue<obj,'T> -> realDataStore:IRealDataStore -> Async<'T>
Full name: Index.realInterpreter
val realDataStore : IRealDataStore
abstract member IRealDataStore.Read : Key -> Async<(Version * string) option>
abstract member IRealDataStore.Write : Key -> Version -> string -> Async<WriteResult>
val interpret2 : prog1:FreeKeyValue<obj,'T> -> prog2:FreeKeyValue<obj,'T> -> dataStore:Map<Key,(Version * string)> -> Map<Key,(Version * string)> * 'T * 'T
Full name: Index.interpret2
val prog1 : FreeKeyValue<obj,'T>
val prog2 : FreeKeyValue<obj,'T>
val runOne : (FreeKeyValue<obj,'a> -> 'b -> Map<Key,(Version * string)> -> 'b * FreeKeyValue<obj,'a> * Map<string,(int * string)>)
val pRun : FreeKeyValue<obj,'a>
val pOther : 'b
val ds : Map<Key,(Version * string)>
val ds' : Map<string,(int * string)>
val pRun' : FreeKeyValue<obj,'a>
val a : 'a
val loop : (FreeKeyValue<obj,'a> * FreeKeyValue<obj,'a> * Map<string,(int * string)> -> Map<string,(int * string)> * 'a * 'a)
val p1 : FreeKeyValue<obj,'a>
val p2 : FreeKeyValue<obj,'a>
val ds : Map<string,(int * string)>
val r1 : 'a
val r2 : 'a
val appendResult2 : Map<Key,(Version * string)> * WriteResult * WriteResult
Full name: Index.appendResult2
Lets see what we can do! with F# Computation Expressions
By Andrew Browne
Seq
1:
2:
3:
4:
5:
6:
7:
|
let seqResult = seq {
yield 1
yield! seq {
yield 2
yield 3
}
}
|
Async
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
|
let readUriAsync(name, url:string) = async {
try
let! html = fetchAsync url
printfn
"Read %d characters for %s"
html.Length
name
with
| ex -> printfn "%s" (ex.Message);
}
|
Option
1:
2:
3:
4:
|
module MyOption =
type Option<'T> =
| Some of 'T
| None
|
Maybe
1:
2:
3:
4:
5:
|
let getCompleteDetails id = maybe {
let! name = lookupName id
let! age = lookupAge id
return (name, age)
}
|
Maybe Desugared
1:
2:
3:
4:
5:
|
let getCompleteDetails2 id =
maybe.Bind(lookupName id, (fun name ->
maybe.Bind(lookupAge id, (fun age ->
maybe.Return((name,age)
)))))
|
Maybe Builder
1:
2:
3:
4:
5:
6:
7:
8:
9:
|
type MaybeBuilder() =
member this.Return(x) = Some x
member this.Bind(input, f) =
match input with
| None -> None
| Some x -> f x
let maybe = MaybeBuilder()
|
Transformations: yield!
1:
2:
3:
|
foo {
yield! 1
}
|
Transformations: return
1:
2:
3:
|
foo {
return 1
}
|
Transformations: return!
1:
2:
3:
|
foo {
return! 1
}
|
Transformations: if else
1:
2:
3:
4:
5:
6:
|
foo {
if true then
return 1
else
return 2
}
|
1:
2:
3:
4:
|
if true then
foo.Return(1)
else
foo.Return(2)
|
Transformations: if
1:
2:
3:
4:
|
foo {
if true then
return 1
}
|
1:
2:
3:
4:
|
if false then
foo.Return(1)
else
foo.Zero()
|
Transformations: use
1:
2:
3:
4:
|
foo {
use a = 1
return a
}
|
1:
|
foo.Using(1, fun a -> foo.Return(a))
|
Transformations: use!
1:
2:
3:
4:
|
foo {
use! a = 1
return a
}
|
1:
2:
3:
4:
5:
|
foo.Bind(
1,
fun a ->
foo.Using(a,
fun a -> foo.Return(a)))
|
Transformations: do!
1:
2:
3:
4:
|
foo {
do! printf "1"
return 2
}
|
1:
2:
3:
|
foo.Bind(
"1",
fun () -> foo.Return(2))
|
Transformations: combine
1:
2:
3:
4:
|
bar {
return "1"
return "2"
}
|
1:
2:
3:
4:
|
bar.Delay(fun () ->
bar.Combine(
bar.Return("1"),
bar.Delay(fun () -> bar.Return("2"))))
|
Transformations: For
1:
2:
3:
4:
|
bar {
for x in [1..3] do
return x
}
|
1:
2:
3:
4:
|
bar.Delay(fun () ->
bar.For(
[1..3],
fun x -> bar.Return(x)))
|
Transformations: While
1:
2:
3:
4:
|
bar {
while true do
return "1"
}
|
1:
2:
3:
4:
|
bar.Delay(fun () ->
bar.While(
(fun () -> true),
bar.Delay(fun () -> bar.Return("1"))))
|
Transformations: Try Finally
1:
2:
3:
4:
5:
6:
|
bar {
try
return "value"
finally
printfn "finally"
}
|
1:
2:
3:
4:
|
bar.Delay(fun () ->
bar.TryFinally(
bar.Delay(fun () -> bar.Return("value")),
fun () -> printfn "finally"))
|
Transformations: Try With
1:
2:
3:
4:
5:
6:
|
bar {
try
return 1 / 0
with | :? System.DivideByZeroException as e ->
return 0
}
|
1:
2:
3:
4:
5:
6:
7:
|
bar.TryWith(
bar.Delay(fun () -> bar.Return(1/0)),
(fun e ->
match e with
| :? System.DivideByZeroException as e ->
bar.Return(0)
| exn -> reraise() ))
|
Async Seq Paging
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
|
let getAllPagesSeq : seq<int> =
let rec loop n = seq {
let results =
getPage n
|> Async.RunSynchronously
yield! results
if results <> Seq.empty then
yield! loop (n + 1)
}
loop 0
|
Async Seq Paging
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
|
let getAllPagesAsync : Async<seq<int>> =
let rec loop n acc = async {
let! results = getPage n
if results <> Seq.empty then
return!
loop (n + 1)
(Seq.append acc results)
else
return acc
}
loop 0 Seq.empty
|
AsyncSeq
1:
2:
3:
4:
5:
|
type AsyncSeq<'T> = Async<AsyncSeqInner<'T>>
and AsyncSeqInner<'T> =
internal
| Nil
| Cons of 'T * AsyncSeq<'T>
|
Async Seq Builder
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
|
type AsyncSeqBuilder() =
member x.Yield(v) = singleton v
member x.YieldFrom (s : seq<'a>) = toAsyncSeq s
member x.YieldFrom (s : AsyncSeq<'a>) = s
member x.Combine (seq1,seq2) =
append seq1 seq2
member x.Bind (inp, body) =
async.Bind(inp, body)
member x.Delay (f:unit -> AsyncSeq<'T>) =
async.Delay(f)
member x.Zero () = empty
|
Async Seq Paging
1:
2:
3:
4:
5:
6:
7:
|
let rec resultLoop n = asyncSeq {
let! results = getPage n
yield! results
if results <> Seq.empty then
yield! resultLoop (n + 1)
}
let getAllResults = resultLoop 0
|
Async Seq Paging
1:
2:
3:
4:
|
let withPageNumber = asyncSeq {
for result in getAllResults do
yield sprintf "Item: %d" result
}
|
Async Seq Paging
1:
2:
3:
4:
5:
|
let filterAsync f (input : AsyncSeq<'T>) =
asyncSeq {
for v in input do
let! b = f v
if b then yield v }
|
A Simple DSL
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
|
let appendValue key value = keyValue {
let! current = readValue key
match current with
| Some (version, currentValue) ->
let newValue = currentValue + value
let! result =
writeValue key (version + 1) newValue
return result
| None ->
let! result = writeValue key 0 value
return result
}
|
A Simple DSL
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
|
type KeyValueLanguage<'N> =
| ReadValue of
Key * ((Version * string) option -> 'N)
| WriteValue of
Key * Version * string * (WriteResult -> 'N)
and
FreeKeyValue<'F,'R> =
| FreeKeyValue of
KeyValueLanguage<FreeKeyValue<'F,'R>>
| Pure of 'R
|
DSL Functions
1:
2:
3:
4:
|
let readValue key =
FreeKeyValue (ReadValue (key, Pure))
let writeValue key version value =
FreeKeyValue (WriteValue (key, version, value, Pure))
|
DSL Interpreter
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
|
let runStep
(prog : FreeKeyValue<obj,'T>)
(dataStore : Map<Key,(Version * string)>)
: InterpeterState<'T> =
match prog with
| FreeKeyValue (ReadValue (key, f)) ->
let value = Map.tryFind key dataStore
let next = f value
Continue (dataStore, next)
| FreeKeyValue (WriteValue (key, version, value, f)) ->
let currentValue = Map.tryFind key dataStore
match currentValue with
| None when version = 0 ->
let dataStore' = Map.add key (version, value) dataStore
Continue (dataStore', f WriteSuccess)
| Some (currentVersion, _) when currentVersion + 1 = version ->
let dataStore' = Map.add key (version, value) dataStore
Continue (dataStore', f WriteSuccess)
| _ ->
Continue (dataStore, f WrongExpectedVersion)
| Pure result ->
Complete (dataStore,result)
|
DSL Interpreter
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
|
let interpret
(prog : FreeKeyValue<obj,'T>)
(dataStore : Map<Key,(Version * string)>)
: (Map<Key,(Version * string)> * 'T) =
let rec loop
(state: InterpeterState<'T>) =
match state with
| Complete r -> r
| Continue (state, p) ->
loop <| runStep p state
loop (Continue (dataStore, prog))
|
DSL Builder
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
|
type KeyValueBuilder() =
member x.Zero() = Pure ()
member x.Return(r:'R) : FreeKeyValue<'F,'R> = Pure r
member x.ReturnFrom(r:FreeKeyValue<'F,'R>) = r
member x.Bind (inp, body) = bind' body inp
member x.Combine(expr1, expr2) = combine expr1 expr2
member x.For(a, f) = forLoop a f
member x.While(func, body) = whileLoop func body
member x.Delay(func) = delay func
let keyValue = new KeyValueBuilder()
|
KeyValue bind
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
|
let fmap f streamWorker =
match streamWorker with
| ReadValue (key, streamRead) ->
ReadValue (key, (streamRead >> f))
| WriteValue (key, expectedVersion, value, next) ->
WriteValue (key, expectedVersion, value, (next >> f))
let rec bind' f v =
match v with
| FreeKeyValue x -> FreeKeyValue (fmap (bind' f) x)
| Pure r -> f r
|
DSL example
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
|
let appendValue key value = keyValue {
let! current = readValue key
match current with
| Some (version, currentValue) ->
let newValue = currentValue + value
let! result =
writeValue key (version + 1) newValue
return result
| None ->
let! result = writeValue key 0 value
return result
}
|
1:
|
let appendResult = interpret (appendValue "key" "abcd") Map.empty
|
(map [("key", (0, "abcd"))], WriteSuccess)
|
DSL example
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
|
let appendValueWithRetry key value =
let rec loop previousResult = keyValue {
match previousResult with
| WrongExpectedVersion ->
return! (appendValue key value)
| _ ->
return previousResult
}
loop WrongExpectedVersion
|
Real DSL Interpreter
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
|
let rec realInterpreter
(prog : FreeKeyValue<obj,'T>)
(realDataStore : IRealDataStore)
: Async<'T> =
match prog with
| FreeKeyValue (ReadValue (key, f)) -> async {
let! value = realDataStore.Read key
return! realInterpreter (f value) realDataStore }
| FreeKeyValue (WriteValue (key, version, value, f)) -> async {
let! result = realDataStore.Write key version value
return! realInterpreter (f result) realDataStore }
| Pure result ->
async { return result }
|
DSL Interpreter Interleaving
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
|
let interpret2
(prog1 : FreeKeyValue<obj,'T>)
(prog2 : FreeKeyValue<obj,'T>)
(dataStore : Map<Key,(Version * string)>)
: (Map<Key,(Version * string)> * 'T * 'T) =
let runOne pRun pOther ds =
match runStep pRun ds with
| Continue (ds',pRun') -> (pOther, pRun', ds')
| Complete(ds', a) -> (pOther, Pure a, ds')
let rec loop
(p1, p2, ds) =
match (p1,p2) with
| (Pure r1, Pure r2) -> (ds,r1, r2)
| (_, Pure _) -> loop <| runOne p1 p2 ds
| _ -> loop <| runOne p2 p1 ds
loop (prog1, prog2, dataStore)
let appendResult2 =
interpret2 (appendValue "key" "abcd") (appendValue "key" "abcd") Map.empty
|
(map [("key", (1, "abcdabcd"))], WriteSuccess, WriteSuccess)
|
More computation expressions
- Choice
- Software Transactional Memory
- Logging
- Parsing