Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- open System.Threading.Tasks
- open FSharp.Control.Tasks.V2
- [<RequireQualifiedAccess>]
- [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
- module Lazy =
- let map (fn : 'T -> 'U) (x : Lazy<'T>) =
- Lazy.Create(fun () -> fn x.Value)
- [<Struct>]
- type Immediate<'T> =
- | Success of value : 'T
- | Failure of error : exn
- override x.ToString() =
- match x with
- | Success v -> "Success(" + v.ToString() + ")"
- | Failure e -> "Failure(" + e.ToString() + ")"
- [<RequireQualifiedAccess>]
- [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
- module Immediate =
- let inline ofValue x = Success x
- let inline zero<'T> = Unchecked.defaultof<'T> |> ofValue
- let create (ctor : unit -> 'T) =
- try Success (ctor ())
- with e -> Failure e
- let inline ofException x = Failure x
- let inline isSuccess x =
- match x with
- | Success _ -> true
- | _ -> false
- let inline isFailure x =
- match x with
- | Failure _ -> true
- | _ -> false
- let get =
- function
- | Success v -> v
- | Failure e -> raise e
- let toAsync =
- function
- | Success v -> async { return v }
- | Failure e -> async { return raise e }
- let toTask =
- function
- | Success v -> task { return v }
- | Failure e -> task { return raise e }
- let toLazy =
- function
- | Success v -> Lazy.CreateFromValue(v)
- | Failure e -> Lazy.Create(fun () -> raise e)
- let map (fn : 'T -> 'U) =
- function
- | Success v -> Success (fn v)
- | Failure e -> Failure e
- let bind (fn : 'T -> Immediate<'U>) =
- function
- | Success v -> fn v
- | Failure e -> Failure e
- let fold (folder : 'State -> 'T -> 'State) (zero : 'State) =
- function
- | Success v -> Success (folder zero v)
- | Failure e -> Failure e
- let rescue (fn : exn -> 'T) =
- function
- | Success v -> Success v
- | Failure e ->
- try Success (fn e)
- with e -> Failure e
- [<Struct>]
- type Awaitable<'T> =
- | Async of async : Async<'T>
- | Task of task : Task<'T>
- override x.ToString() =
- match x with
- | Async a -> "Async(" + a.ToString() + ")"
- | Task t -> "Task(" + t.ToString() + ")"
- [<RequireQualifiedAccess>]
- [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
- module Awaitable =
- let inline ofValue x = async { return x } |> Async
- let inline zero<'T> = Unchecked.defaultof<'T> |> ofValue
- let inline isAsync x =
- match x with
- | Async _ -> true
- | _ -> false
- let inline isTask x =
- match x with
- | Task _ -> false
- | _ -> true
- let inline ofAsync x = Async x
- let inline ofTask x = Task x
- let ofPlainTask (x : Task) = task { do! x } |> Task
- let ofEvent x = Async.AwaitEvent(x) |> Async
- let ofLazy (x : Lazy<'T>) = async { return x.Value } |> Async
- let ofException (x : exn) = async { return raise x } |> Async
- let inline ofImmediate x =
- match x with
- | Success x -> ofValue x
- | Failure e -> ofException e
- let get =
- function
- | Async a -> Async.RunSynchronously(a)
- | Task t -> t.Result
- let toImmediate x =
- try Success (get x)
- with e -> Failure e
- let toAsync =
- function
- | Async a -> a
- | Task t -> Async.AwaitTask(t)
- let toTask =
- function
- | Async a -> task { return! a }
- | Task t -> t
- let toLazy x = Lazy.Create(fun () -> get x)
- let map (fn : 'T -> 'U) =
- function
- | Async a ->
- async {
- let! value = a
- return fn value
- } |> Async
- | Task t ->
- task {
- let! value = t
- return fn value
- } |> Task
- let bind (fn : 'T -> Awaitable<'U>) =
- function
- | Async a ->
- async {
- let! value = a
- return! toAsync (fn value)
- } |> Async
- | Task t ->
- task {
- let! value = t
- return! toTask (fn value)
- } |> Task
- let fold (folder : 'State -> 'T -> 'State) (zero : 'State) =
- function
- | Async a ->
- async {
- let! value = a
- return folder zero value
- } |> Async
- | Task t ->
- task {
- let! value = t
- return folder zero value
- } |> Task
- let rescue (fn : exn -> 'T) =
- function
- | Async a ->
- async {
- try return! a
- with e -> return fn e
- } |> Async
- | Task t ->
- task {
- try return! t
- with e -> return fn e
- } |> Task
- let private collectParallelAsync (values : Awaitable<'T> []) =
- Array.map toAsync values |> Async.Parallel |> Async
- let private collectParallelTask (values : Awaitable<'T> []) =
- Array.map toTask values |> Task.WhenAll |> Task
- let collectParallel (values : Awaitable<'T> []) =
- if Array.forall isTask values
- then collectParallelTask values
- else collectParallelAsync values
- let private collectSequentialAsync (values : Awaitable<'T> []) =
- async {
- let results = Array.zeroCreate values.Length
- let asyncValues = values|> Array.map toAsync
- for i = 0 to values.Length - 1 do
- let! value = asyncValues.[i]
- results.[i] <- value
- return results
- } |> Async
- let private collectSequentialTask (values : Awaitable<'T> []) =
- task {
- let results = Array.zeroCreate values.Length
- let asyncValues = values|> Array.map toAsync
- for i = 0 to values.Length - 1 do
- let! value = asyncValues.[i]
- results.[i] <- value
- return results
- } |> Task
- let collectSequential (values : Awaitable<'T> []) =
- if Array.forall isTask values
- then collectSequentialTask values
- else collectSequentialAsync values
- let appendParallel (values : Awaitable<'T []> []) =
- values
- |> collectParallel
- |> map (Array.fold Array.append [||])
- let appendSequential (values : Awaitable<'T []> []) =
- values
- |> collectSequential
- |> map (Array.fold Array.append [||])
- [<Struct>]
- type Value<'T> =
- | Immediate of immediateValue : Immediate<'T>
- | Awaitable of awaitableValue : Awaitable<'T>
- | Lazy of lazyValue : Lazy<'T>
- override x.ToString() =
- match x with
- | Immediate i -> "Immediate(" + i.ToString() + ")"
- | Awaitable a -> "Awaitable(" + a.ToString() + ")"
- | Lazy l -> "Lazy(" + l.ToString() + ")"
- type 'T value = Value<'T>
- [<RequireQualifiedAccess>]
- [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
- module Value =
- let inline ofValue x = Immediate.ofValue x |> Immediate
- let inline zero<'T> = Unchecked.defaultof<'T> |> ofValue
- let inline isImmediate x =
- match x with
- | Immediate _ -> true
- | _ -> false
- let inline isAwaitable x =
- match x with
- | Awaitable _ -> true
- | _ -> false
- let inline isLazy x =
- match x with
- | Lazy _ -> true
- | _ -> false
- let inline ofImmediate x = Immediate x
- let inline ofAwaitable x = Awaitable x
- let inline ofLazy x = Lazy x
- let inline ofException x = Immediate.ofException x |> Immediate
- let inline ofAsync x = Awaitable.ofAsync x |> Awaitable
- let inline ofTask x = Awaitable.ofTask x |> Awaitable
- let inline ofPlainTask x = Awaitable.ofPlainTask x |> Awaitable
- let get =
- function
- | Immediate x -> Immediate.get x
- | Awaitable x -> Awaitable.get x
- | Lazy l -> l.Value
- let toImmediate =
- function
- | Immediate x -> x
- | Awaitable x -> Awaitable.toImmediate x
- | Lazy l -> Immediate.create l.Force
- let toAwaitable =
- function
- | Immediate x -> Awaitable.ofImmediate x
- | Awaitable x -> x
- | Lazy l -> Awaitable.ofLazy l
- let toLazy =
- function
- | Immediate x -> Immediate.toLazy x
- | Awaitable x -> Awaitable.toLazy x
- | Lazy l -> l
- let toAsync =
- function
- | Immediate x -> Immediate.toAsync x
- | Awaitable x -> Awaitable.toAsync x
- | Lazy l -> async { return l.Value }
- let toTask =
- function
- | Immediate x -> Immediate.toTask x
- | Awaitable x -> Awaitable.toTask x
- | Lazy l -> task { return l.Value }
- let map (fn : 'T -> 'U) =
- function
- | Immediate x -> x |> Immediate.map fn |> Immediate
- | Awaitable x -> x |> Awaitable.map fn |> Awaitable
- | Lazy l -> l |> Lazy.map fn |> Lazy
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement