Skip to content

Commit

Permalink
Add support for ValueTask (#523)
Browse files Browse the repository at this point in the history
  • Loading branch information
rodriguestiago0 authored Nov 28, 2022
1 parent e3f71e8 commit 3c05e4b
Show file tree
Hide file tree
Showing 21 changed files with 311 additions and 27 deletions.
9 changes: 8 additions & 1 deletion .github/workflows/fable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,14 @@ jobs:
run: git submodule update --init --recursive
- name: Remove global json
run: rm global.json
- name: Setup .NET Core
- name: Remove global json in subfolder
run: rm global.json
working-directory: tests/FSharpPlusFable.Tests
- name: Setup .NET Core 7
uses: actions/setup-dotnet@v1
with:
dotnet-version: 7.0.100
- name: Setup .NET Core 6
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.201
Expand Down
11 changes: 11 additions & 0 deletions FSharpPlus.sln
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharpPlusFable.Tests", "te
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Benchmarks", "tests\benchmarks\Benchmarks.fsproj", "{EEFF08EB-8B0C-4F63-9425-4281EFF12087}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "docsTool", "docsrc\tools\docsTool.fsproj", "{ACBBD11E-0746-4B9D-9CED-A90FE5824CE2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -169,6 +171,14 @@ Global
{EEFF08EB-8B0C-4F63-9425-4281EFF12087}.Fable|Any CPU.Build.0 = Debug|Any CPU
{EEFF08EB-8B0C-4F63-9425-4281EFF12087}.Fable3|Any CPU.ActiveCfg = Debug|Any CPU
{EEFF08EB-8B0C-4F63-9425-4281EFF12087}.Fable3|Any CPU.Build.0 = Debug|Any CPU
{ACBBD11E-0746-4B9D-9CED-A90FE5824CE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ACBBD11E-0746-4B9D-9CED-A90FE5824CE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ACBBD11E-0746-4B9D-9CED-A90FE5824CE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ACBBD11E-0746-4B9D-9CED-A90FE5824CE2}.Release|Any CPU.Build.0 = Release|Any CPU
{ACBBD11E-0746-4B9D-9CED-A90FE5824CE2}.Fable|Any CPU.ActiveCfg = Debug|Any CPU
{ACBBD11E-0746-4B9D-9CED-A90FE5824CE2}.Fable|Any CPU.Build.0 = Debug|Any CPU
{ACBBD11E-0746-4B9D-9CED-A90FE5824CE2}.Fable3|Any CPU.ActiveCfg = Debug|Any CPU
{ACBBD11E-0746-4B9D-9CED-A90FE5824CE2}.Fable3|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -182,6 +192,7 @@ Global
{7A5B766E-8141-4D8A-B3EB-91422FDBDF71} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4}
{1CCD1BFB-60E4-40AA-B534-3C5EEE5E1E83} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4}
{EEFF08EB-8B0C-4F63-9425-4281EFF12087} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4}
{ACBBD11E-0746-4B9D-9CED-A90FE5824CE2} = {83F16175-43B1-4C90-A1EE-8E351C33435D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {789B5FFA-7891-4F60-831E-42C3C5ED2C51}
Expand Down
1 change: 1 addition & 0 deletions docsrc/content/abstraction-applicative.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ From F#
- ``KeyValuePair<'Key,'T>``
- ``'Monoid * 'T``
- ``Task<'T>``
- ``ValueTask<'T>``
- ``'R->'T``
- ``Expr<'T>``
- ``ResizeArray<'T>``
Expand Down
1 change: 1 addition & 0 deletions docsrc/content/abstraction-comonad.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ From .Net/F#
- ``Id<'T>``
- ``('W * 'T)``
- ``'Monoid -> 'T``
- ``ValueTask<'T>``
From F#+
Expand Down
1 change: 1 addition & 0 deletions docsrc/content/abstraction-functor.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ From F#
- ``Map<'Key,'T>``
- ``'Monoid * 'T``
- ``Task<'T>``
- ``ValueTask<'T>``
- ``'R->'T``
- ``Expr<'T>``
- ``Dictionary<'Key,'T>``
Expand Down
1 change: 1 addition & 0 deletions docsrc/content/abstraction-monad.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ From F#
- ``Choice<'T,'U>``
- ``'Monoid * 'T``
- ``Task<'T>``
- ``ValueTask<'T>``
- ``'R->'T``
- ``ResizeArray<'T>``
Expand Down
1 change: 1 addition & 0 deletions docsrc/content/abstraction-monoid.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ From .Net/F#
- ``Tuple<'Monoid1* ... *'MonoidN>``
- ``'Monoid1* ... *'MonoidN``
- ``Task<'T>``
- ``ValueTask<'T>``
- ``'T->'Monoid``
- ``Async<'T>``
- ``Expr<'T>``
Expand Down
1 change: 1 addition & 0 deletions docsrc/content/abstraction-semigroup.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ From .Net/F#
- ``Tuple<*>``
- ``'T1* ... *'Tn``
- ``Task<'T>``
- ``ValueTask<'T>``
- ``'T->'Semigroup``
- ``Async<'T>``
- ``Expr<'T>``
Expand Down
10 changes: 8 additions & 2 deletions docsrc/content/extensions.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -259,14 +259,20 @@ Collections / Traversable types:
* zip, unzip,
* unionWith, union, intersectWith, intersect
Async and Tasks:
================
Async, Task and ValueTask:
==========================
* [ Task ](reference/fsharpplus-task.html)
* map, map2, map3
* apply
* zip
* join
* ignore
* [ ValueTask ](reference/fsharpplus-valueTask.html)
* map, map2, map3
* apply
* zip
* join
* ignore
* [ Async ](reference/fsharpplus-async.html)
* map, map2
* zip
Expand Down
9 changes: 9 additions & 0 deletions src/FSharpPlus/Control/Applicative.fs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ type Apply =
#if !FABLE_COMPILER
static member ``<*>`` (f: Task<_> , x: Task<'T> , [<Optional>]_output: Task<'U> , [<Optional>]_mthd: Apply) = Task.apply f x : Task<'U>
#endif
#if NETSTANDARD2_1 && !FABLE_COMPILER
static member ``<*>`` (f: ValueTask<_> , x: ValueTask<'T> , [<Optional>]_output: ValueTask<'U> , [<Optional>]_mthd: Apply) = ValueTask.apply f x : ValueTask<'U>
#endif
static member ``<*>`` (f: Async<_> , x: Async<'T> , [<Optional>]_output: Async<'U> , [<Optional>]_mthd: Apply) = Async.apply f x : Async<'U>
static member ``<*>`` (f: option<_> , x: option<'T> , [<Optional>]_output: option<'U> , [<Optional>]_mthd: Apply) = Option.apply f x : option<'U>
static member ``<*>`` (f: voption<_> , x: voption<'T> , [<Optional>]_output: voption<'U> , [<Optional>]_mthd: Apply) = ValueOption.apply f x : voption<'U>
Expand Down Expand Up @@ -82,6 +85,9 @@ type Lift2 =
#if !FABLE_COMPILER
static member Lift2 (f, (x: Task<'T> , y: Task<'U> ), _mthd: Lift2) = Task.map2 f x y
#endif
#if NETSTANDARD2_1 && !FABLE_COMPILER
static member Lift2 (f, (x: ValueTask<'T> , y: ValueTask<'U> ), _mthd: Lift2) = ValueTask.map2 f x y
#endif
static member Lift2 (f, (x , y ), _mthd: Lift2) = Async.map2 f x y
static member Lift2 (f, (x , y ), _mthd: Lift2) = Option.map2 f x y

Expand Down Expand Up @@ -124,6 +130,9 @@ type Lift3 =
#if !FABLE_COMPILER
static member Lift3 (f, (x: Task<'T> , y: Task<'U> , z: Task<'V> ), _mthd: Lift3) = Task.map3 f x y z
#endif
#if NETSTANDARD2_1 && !FABLE_COMPILER
static member Lift3 (f, (x: ValueTask<'T> , y: ValueTask<'U> , z: ValueTask<'V> ), _mthd: Lift3) = ValueTask.map3 f x y z
#endif
static member Lift3 (f, (x , y , z ), _mthd: Lift3) = Async.map3 f x y z
static member Lift3 (f, (x , y , z ), _mthd: Lift3) = Option.map3 f x y z

Expand Down
11 changes: 11 additions & 0 deletions src/FSharpPlus/Control/Comonad.fs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ type Extract =
#if !FABLE_COMPILER
static member Extract (f: Task<'T> ) = f.Result
#endif
#if NETSTANDARD2_1 && !FABLE_COMPILER
static member Extract (f: ValueTask<'T> ) = f.Result
#endif
static member inline Invoke (x: '``Comonad<'T>``) : 'T =
let inline call_2 (_mthd: ^M, x: ^I) = ((^M or ^I) : (static member Extract : _ -> _) x)
call_2 (Unchecked.defaultof<Extract>, x)
Expand Down Expand Up @@ -57,6 +60,14 @@ type Extend =
elif k.Status = TaskStatus.Canceled then tcs.SetCanceled ()
elif k.Status = TaskStatus.Faulted then tcs.SetException k.Exception.InnerExceptions) |> ignore
tcs.Task


#endif
#if NETSTANDARD2_1 && !FABLE_COMPILER
static member (=>>) (g: ValueTask<'T> , f: ValueTask<'T> -> 'U ) : ValueTask<'U> =
backgroundTask {
return! f g
} |> ValueTask<'U>
#endif

// Restricted Comonads
Expand Down
9 changes: 9 additions & 0 deletions src/FSharpPlus/Control/Functor.fs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ type Map =
#if !FABLE_COMPILER
static member Map ((x: Task<'T> , f: 'T->'U), _mthd: Map) = Task.map f x : Task<'U>
#endif
#if NETSTANDARD2_1 && !FABLE_COMPILER
static member Map ((x: ValueTask<'T> , f: 'T->'U), _mthd: Map) = ValueTask.map f x : ValueTask<'U>
#endif
static member Map ((x: option<_> , f: 'T->'U), _mthd: Map) = Option.map f x
#if !FABLE_COMPILER
static member Map ((x: voption<_> , f: 'T->'U), _mthd: Map) = ValueOption.map f x
Expand Down Expand Up @@ -148,6 +151,9 @@ type Unzip =
#if !FABLE_COMPILER
static member Unzip ((source: Task<'T * 'U> , _output: Task<'T> * Task<'U> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
#endif
#if NETSTANDARD2_1 && !FABLE_COMPILER
static member Unzip ((source: ValueTask<'T * 'U> , _output: ValueTask<'T> * ValueTask<'U> ) , _mthd: Unzip ) = Map.Invoke fst source, Map.Invoke snd source
#endif
static member Unzip ((source: option<'T * 'U> , _output: option<'T> * option<'U> ) , _mthd: Unzip ) = Option.unzip source
static member Unzip ((source: voption<'T * 'U> , _output: voption<'T> * voption<'U> ) , _mthd: Unzip ) = ValueOption.unzip source

Expand Down Expand Up @@ -214,6 +220,9 @@ type Zip =
#if !FABLE_COMPILER
static member Zip ((x: Task<'T> , y: Task<'U> , _output: Task<'T*'U> ), _mthd: Zip) = Task.zip x y
#endif
#if NETSTANDARD2_1 && !FABLE_COMPILER
static member Zip ((x: ValueTask<'T> , y: ValueTask<'U> , _output: ValueTask<'T*'U> ), _mthd: Zip) = ValueTask.zip x y
#endif

static member inline Invoke (source1: '``ZipFunctor<'T1>``) (source2: '``ZipFunctor<'T2>``) =
let inline call_4 (a: ^a, b: ^b, c: ^c, d: ^d) = ((^a or ^b or ^c or ^d) : (static member Zip : (_*_*_)*_ -> _) (b, c, d), a)
Expand Down
36 changes: 25 additions & 11 deletions src/FSharpPlus/Control/Monad.fs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@ open FSharpPlus.Internals.Prelude
// Monad class ------------------------------------------------------------

type Bind =
static member (>>=) (source: Lazy<'T> , f: 'T -> Lazy<'U> ) = lazy (f source.Value).Value : Lazy<'U>
static member (>>=) (source: seq<'T> , f: 'T -> seq<'U> ) = Seq.bind f source : seq<'U>
static member (>>=) (source: Lazy<'T> , f: 'T -> Lazy<'U> ) = lazy (f source.Value).Value : Lazy<'U>
static member (>>=) (source: seq<'T> , f: 'T -> seq<'U> ) = Seq.bind f source : seq<'U>
#if !FABLE_COMPILER
static member (>>=) (source: Task<'T> , f: 'T -> Task<'U> ) = Task.bind f source : Task<'U>
static member (>>=) (source , f: 'T -> _ ) = Nullable.bind f source : Nullable<'U>
static member (>>=) (source: Task<'T> , f: 'T -> Task<'U> ) = Task.bind f source : Task<'U>
static member (>>=) (source , f: 'T -> _ ) = Nullable.bind f source : Nullable<'U>
#endif
#if NETSTANDARD2_1 && !FABLE_COMPILER
static member (>>=) (source: ValueTask<'T> , f: 'T -> ValueTask<'U> ) = ValueTask.bind f source : ValueTask<'U>
#endif

static member (>>=) (source , f: 'T -> _ ) = Option.bind f source : option<'U>
#if !FABLE_COMPILER
static member (>>=) (source , f: 'T -> _ ) = ValueOption.bind f source : voption<'U>
Expand Down Expand Up @@ -69,13 +73,16 @@ type Bind =

type Join =
inherit Default1
static member inline Join (x: '``Monad<'Monad<'T>>``, [<Optional>]_output: '``Monad<'T>`` , [<Optional>]_mthd: Default2) = Bind.InvokeOnInstance x id : '``Monad<'T>``
static member inline Join (x: '``Monad<'Monad<'T>>``, [<Optional>]_output: '``Monad<'T>`` , [<Optional>]_mthd: Default1) = ((^``Monad<'Monad<'T>>`` or ^``Monad<'T>``) : (static member Join : _ -> _) x) : '``Monad<'T>``
static member Join (x: Lazy<Lazy<_>> , [<Optional>]_output: Lazy<'T> , [<Optional>]_mthd: Join ) = lazy x.Value.Value : Lazy<'T>
static member Join (x: seq<seq<_>> , [<Optional>]_output: seq<'T> , [<Optional>]_mthd: Join ) = Seq.concat x : seq<'T>
static member Join (x: Id<_> , [<Optional>]_output: Id<'T> , [<Optional>]_mthd: Join ) = x.getValue : Id<'T>
#if !FABLE_COMPILER
static member Join (x: Task<Task<_>> , [<Optional>]_output: Task<'T> , [<Optional>]_mthd: Join ) = Task.join x : Task<'T>
static member inline Join (x: '``Monad<'Monad<'T>>`` , [<Optional>]_output: '``Monad<'T>`` , [<Optional>]_mthd: Default2) = Bind.InvokeOnInstance x id : '``Monad<'T>``
static member inline Join (x: '``Monad<'Monad<'T>>`` , [<Optional>]_output: '``Monad<'T>`` , [<Optional>]_mthd: Default1) = ((^``Monad<'Monad<'T>>`` or ^``Monad<'T>``) : (static member Join : _ -> _) x) : '``Monad<'T>``
static member Join (x: Lazy<Lazy<_>> , [<Optional>]_output: Lazy<'T> , [<Optional>]_mthd: Join ) = lazy x.Value.Value : Lazy<'T>
static member Join (x: seq<seq<_>> , [<Optional>]_output: seq<'T> , [<Optional>]_mthd: Join ) = Seq.concat x : seq<'T>
static member Join (x: Id<_> , [<Optional>]_output: Id<'T> , [<Optional>]_mthd: Join ) = x.getValue : Id<'T>
#if !FABLE_COMPILER
static member Join (x: Task<Task<_>> , [<Optional>]_output: Task<'T> , [<Optional>]_mthd: Join ) = Task.join x : Task<'T>
#endif
#if NETSTANDARD2_1 && !FABLE_COMPILER
static member Join (x: ValueTask<ValueTask<_>> , [<Optional>]_output: ValueTask<'T> , [<Optional>]_mthd: Join ) = ValueTask.join x : ValueTask<'T>
#endif
static member Join (x , [<Optional>]_output: option<'T> , [<Optional>]_mthd: Join ) = Option.flatten x : option<'T>
#if !FABLE_COMPILER
Expand Down Expand Up @@ -134,6 +141,9 @@ type Return =
#if !FABLE_COMPILER
static member Return (_: 'T Task , _: Return ) = fun x -> Task.FromResult x : 'T Task
#endif
#if NETSTANDARD2_1 && !FABLE_COMPILER
static member Return (_: 'T ValueTask , _: Return ) = fun x -> ValueTask.FromResult x : 'T ValueTask
#endif
static member Return (_: option<'a> , _: Return ) = fun x -> Some x : option<'a>
static member Return (_ : voption<'a> , _: Return ) = fun x -> ValueSome x : voption<'a>
static member Return (_: list<'a> , _: Return ) = fun x -> [ x ] : list<'a>
Expand Down Expand Up @@ -180,6 +190,10 @@ type Delay =
static member inline Invoke (source : unit -> '``Monad<'T>``) : '``Monad<'T>`` = Bind.Invoke (Return.Invoke ()) source

#endif

#if NETSTANDARD2_1 && !FABLE_COMPILER
static member Delay (_mthd: Delay , x: unit-> ValueTask<_> , _ ) = x () : ValueTask<'T>
#endif


[<System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)>]
Expand Down
8 changes: 8 additions & 0 deletions src/FSharpPlus/Control/Monoid.fs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ type Plus with
static member inline ``+`` (x: 'a Task, y: 'a Task, [<Optional>]_mthd: Plus) = Task.map2 Plus.Invoke x y
#endif

#if NETSTANDARD2_1 && !FABLE_COMPILER
type Plus with

static member inline ``+`` (x: 'a ValueTask, y: 'a ValueTask, [<Optional>]_mthd: Plus) = ValueTask.map2 Plus.Invoke x y

#endif


static member inline ``+`` (x: Map<'a,'b> , y , [<Optional>]_mthd: Plus) = Map.unionWith Plus.Invoke x y

static member inline ``+`` (x: Dictionary<'Key,'Value>, y: Dictionary<'Key,'Value>, [<Optional>]_mthd: Plus) =
Expand Down
5 changes: 5 additions & 0 deletions src/FSharpPlus/Control/Numeric.fs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ type Zero with
s.SetResult v
s.Task
#endif
#if NETSTANDARD2_1 && !FABLE_COMPILER
static member inline Zero (_: ValueTask<'a>, _: Zero) : ValueTask<'a> =
let (v: 'a) = Zero.Invoke ()
ValueTask<'a>(v)
#endif
static member inline Zero (_: 'T->'Monoid , _: Zero) = (fun _ -> Zero.Invoke ()) : 'T->'Monoid
static member inline Zero (_: Async<'a> , _: Zero) = let (v: 'a) = Zero.Invoke () in async.Return v
#if !FABLE_COMPILER
Expand Down
6 changes: 3 additions & 3 deletions src/FSharpPlus/Extensions/Task.fs
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,13 @@ module Task =
else
let tcs = TaskCompletionSource<unit> ()
if task.Status = TaskStatus.Faulted then
tcs.SetException task.Exception.InnerExceptions |> ignore
tcs.SetException task.Exception.InnerExceptions
elif task.Status = TaskStatus.Canceled then
tcs.SetCanceled ()
else
let k (t: Task) : unit =
if t.IsCanceled then tcs.SetCanceled () |> ignore
elif t.IsFaulted then tcs.SetException t.Exception |> ignore
if t.IsCanceled then tcs.SetCanceled ()
elif t.IsFaulted then tcs.SetException t.Exception
else tcs.SetResult ()
task.ContinueWith k |> ignore
tcs.Task
Expand Down
Loading

0 comments on commit 3c05e4b

Please sign in to comment.