Skip to content

Commit 9557a86

Browse files
committed
Merge branch 'pr/99' into forloop-with-iasyncenumerable-with-task-and-async
2 parents 6eac005 + c2d117c commit 9557a86

File tree

3 files changed

+74
-24
lines changed

3 files changed

+74
-24
lines changed

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

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,20 @@ 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+
}

src/FSharp.Control.TaskSeq/TaskSeq.fs

Lines changed: 55 additions & 8 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,27 +389,72 @@ 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+
TaskCode<_, _>(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 <- awaiter.GetResult()
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>,
401-
body: 'T -> TaskCode<'TOverall, unit>
402-
) : TaskCode<'TOverall, unit> =
433+
body: 'T -> TaskCode<_, unit>
434+
) : TaskCode<_, unit> =
435+
// tasksq
436+
// |> TaskSeq.iterAsync (body >> task.Run)
437+
// |> task.ReturnFrom
438+
439+
// task.ReturnFrom <|
440+
// task {
441+
// let mutable continueWhile = true
442+
// use e = tasksq.GetAsyncEnumerator()
443+
// while continueWhile do
444+
// let! next = e.MoveNextAsync()
445+
// if next then
446+
// do! task.Run(body e.Current)
447+
// else
448+
// continueWhile <- false
449+
// }
450+
403451
TaskCode<'TOverall, unit>(fun sm ->
404452

405453
this
406454
.Using(
407455
tasksq.GetAsyncEnumerator(CancellationToken()),
408456
(fun e ->
409-
let next () = e.MoveNextAsync()
410-
this.While(next, (fun sm -> (body e.Current).Invoke(&sm))))
457+
this.WhileAsync(e.MoveNextAsync, (fun sm -> (body e.Current).Invoke(&sm))))
411458
)
412459
.Invoke(&sm))
413460

src/FSharp.Control.TaskSeq/TaskSeq.fsi

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -594,11 +594,10 @@ 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>) ->
603603
TaskCode<'TOverall, unit>
604-

0 commit comments

Comments
 (0)