Skip to content

Commit 15e3ed1

Browse files
TheAngryByrdabelbraaksma
authored andcommitted
WhileAsync statically compiled
1 parent 9190789 commit 15e3ed1

File tree

3 files changed

+57
-20
lines changed

3 files changed

+57
-20
lines changed

src/FSharp.Control.TaskSeq.Test/TaskSeq.Extensions.Tests.fs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,21 @@ open FSharp.Control
1313
//
1414

1515

16-
// module TaskBuilder =
17-
// open TaskSeq.Tests
18-
19-
// [<Theory; ClassData(typeof<TestImmTaskSeq>)>]
20-
// let ``TaskSeq-existsAsync happy path last item of seq`` variant =
21-
// task {
22-
// let values = Gen.getSeqImmutable variant
23-
// let mutable sum = 0
24-
// for x in values do
25-
// sum <- sum + x
26-
// }
27-
// |> TaskSeq.existsAsync (fun x -> task { return x = 10 })
28-
// |> Task.map (should be True)
16+
module TaskBuilder =
17+
open TaskSeq.Tests
18+
19+
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
20+
let ``TaskSeq-existsAsync happy path last item of seq`` variant =
21+
task {
22+
let values = Gen.getSeqImmutable variant
23+
24+
let mutable sum = 0
25+
for x in values do
26+
sum <- sum + x
27+
28+
// let! expected =
29+
// (0, values)
30+
// ||> TaskSeq.fold((+))
31+
Assert.Equal(55, sum)
32+
}
33+

src/FSharp.Control.TaskSeq/TaskSeq.fs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,8 @@ module AsyncSeqExtensions =
371371

372372
false
373373
open Microsoft.FSharp.Core.CompilerServices
374+
open Microsoft.FSharp.Core.CompilerServices.StateMachineHelpers
375+
open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
374376

375377
// Add asynchronous for loop to the 'async' computation builder
376378
type Microsoft.FSharp.Control.AsyncBuilder with
@@ -384,14 +386,44 @@ module AsyncSeqExtensions =
384386
type Microsoft.FSharp.Control.TaskBuilder with
385387

386388

387-
member inline this.While(condition : unit -> ValueTask<bool>, body : TaskCode<'TOverall,unit>) =
388-
TaskCode<_,_>(fun sm ->
389-
WhileDynamic(&sm, condition, body)
389+
member inline _.WhileAsync
390+
(
391+
[<InlineIfLambda>] condition: unit -> ValueTask<bool>,
392+
body: TaskCode<_,unit>
393+
) : TaskCode<_,_> =
394+
let mutable condition_res = true
395+
396+
ResumableCode.While(
397+
(fun () -> condition_res),
398+
ResumableCode<_, _>(fun sm ->
399+
let mutable __stack_condition_fin = true
400+
let __stack_vtask = condition ()
401+
402+
let mutable awaiter = __stack_vtask.GetAwaiter()
403+
if awaiter.IsCompleted then
404+
// logInfo "at WhileAsync: returning completed task"
405+
406+
__stack_condition_fin <- true
407+
condition_res <- __stack_vtask.Result
408+
else
409+
// logInfo "at WhileAsync: awaiting non-completed task"
390410

391-
)
411+
// This will yield with __stack_fin = false
412+
// This will resume with __stack_fin = true
413+
let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm)
414+
__stack_condition_fin <- __stack_yield_fin
392415

416+
if __stack_condition_fin then
417+
condition_res <- awaiter.GetResult()
393418

394419

420+
if __stack_condition_fin then
421+
if condition_res then body.Invoke(&sm) else true
422+
else
423+
sm.Data.MethodBuilder.AwaitUnsafeOnCompleted(&awaiter, &sm)
424+
false)
425+
)
426+
395427
member inline this.For
396428
(
397429
tasksq: IAsyncEnumerable<'T>,
@@ -404,7 +436,7 @@ module AsyncSeqExtensions =
404436
tasksq.GetAsyncEnumerator(CancellationToken()),
405437
(fun e ->
406438
let next () = e.MoveNextAsync()
407-
this.While(next, (fun sm -> (body e.Current).Invoke(&sm))))
439+
this.WhileAsync(next, (fun sm -> (body e.Current).Invoke(&sm))))
408440
)
409441
.Invoke(&sm))
410442

src/FSharp.Control.TaskSeq/TaskSeq.fsi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,9 +589,9 @@ module AsyncSeqExtensions =
589589

590590
type TaskBuilder with
591591

592-
member inline While:
592+
member inline WhileAsync:
593593
condition: (unit -> System.Threading.Tasks.ValueTask<bool>) * body: TaskCode<'TOverall, unit> ->
594-
TaskCode<'TOverall, 'a>
594+
TaskCode<'TOverall, unit>
595595

596596
member inline For:
597597
tasksq: System.Collections.Generic.IAsyncEnumerable<'T> * body: ('T -> TaskCode<'TOverall, unit>) ->

0 commit comments

Comments
 (0)