Skip to content

Commit 57e7cee

Browse files
TheAngryByrdabelbraaksma
authored andcommitted
WhileAsync statically compiled
1 parent 4481e79 commit 57e7cee

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
@@ -374,6 +374,8 @@ module AsyncSeqExtensions =
374374

375375
false
376376
open Microsoft.FSharp.Core.CompilerServices
377+
open Microsoft.FSharp.Core.CompilerServices.StateMachineHelpers
378+
open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
377379

378380
// Add asynchronous for loop to the 'async' computation builder
379381
type Microsoft.FSharp.Control.AsyncBuilder with
@@ -387,14 +389,44 @@ module AsyncSeqExtensions =
387389
type Microsoft.FSharp.Control.TaskBuilder with
388390

389391

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

394-
)
414+
// This will yield with __stack_fin = false
415+
// This will resume with __stack_fin = true
416+
let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm)
417+
__stack_condition_fin <- __stack_yield_fin
395418

419+
if __stack_condition_fin then
420+
condition_res <- awaiter.GetResult()
396421

397422

423+
if __stack_condition_fin then
424+
if condition_res then body.Invoke(&sm) else true
425+
else
426+
sm.Data.MethodBuilder.AwaitUnsafeOnCompleted(&awaiter, &sm)
427+
false)
428+
)
429+
398430
member inline this.For
399431
(
400432
tasksq: IAsyncEnumerable<'T>,
@@ -407,7 +439,7 @@ module AsyncSeqExtensions =
407439
tasksq.GetAsyncEnumerator(CancellationToken()),
408440
(fun e ->
409441
let next () = e.MoveNextAsync()
410-
this.While(next, (fun sm -> (body e.Current).Invoke(&sm))))
442+
this.WhileAsync(next, (fun sm -> (body e.Current).Invoke(&sm))))
411443
)
412444
.Invoke(&sm))
413445

src/FSharp.Control.TaskSeq/TaskSeq.fsi

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

595595
type TaskBuilder with
596596

597-
member inline While:
597+
member inline WhileAsync:
598598
condition: (unit -> System.Threading.Tasks.ValueTask<bool>) * body: TaskCode<'TOverall, unit> ->
599-
TaskCode<'TOverall, 'a>
599+
TaskCode<'TOverall, unit>
600600

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

0 commit comments

Comments
 (0)