Skip to content

Commit 5048b82

Browse files
committed
Add implementation for TaskSeq.delay
1 parent 73ce192 commit 5048b82

File tree

5 files changed

+70
-1
lines changed

5 files changed

+70
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ The following is the progress report:
8383
| | `compareWith` | `compareWith` | `compareWithAsync` | |
8484
| ✅ [#69][] | `concat` | `concat` | | |
8585
| ✅ [#70][] | `contains` | `contains` | | |
86-
| | `delay` | `delay` | | |
86+
| ✅ [#82][] | `delay` | `delay` | | |
8787
| | `distinct` | `distinct` | | |
8888
| | `distinctBy` | `dictinctBy` | `distinctByAsync` | |
8989
| ✅ [#2][] | `empty` | `empty` | | |
@@ -610,4 +610,5 @@ module TaskSeq =
610610
[#70]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/70
611611
[#76]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/76
612612
[#81]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/81
613+
[#82]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/82
613614

src/FSharp.Control.TaskSeq.Test/FSharp.Control.TaskSeq.Test.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<Compile Include="TaskSeq.Collect.Tests.fs" />
1919
<Compile Include="TaskSeq.Concat.Tests.fs" />
2020
<Compile Include="TaskSeq.Contains.Tests.fs" />
21+
<Compile Include="TaskSeq.Delay.Tests.fs" />
2122
<Compile Include="TaskSeq.Empty.Tests.fs" />
2223
<Compile Include="TaskSeq.ExactlyOne.Tests.fs" />
2324
<Compile Include="TaskSeq.Exists.Tests.fs" />
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
module TaskSeq.Tests.Delay
2+
3+
open System
4+
5+
open Xunit
6+
open FsUnit.Xunit
7+
open FsToolkit.ErrorHandling
8+
9+
open FSharp.Control
10+
open System.Collections.Generic
11+
12+
//
13+
// TaskSeq.delay
14+
//
15+
16+
let validateSequence ts =
17+
ts
18+
|> TaskSeq.toSeqCachedAsync
19+
|> Task.map (Seq.map string)
20+
|> Task.map (String.concat "")
21+
|> Task.map (should equal "12345678910")
22+
23+
module EmptySeq =
24+
[<Theory; ClassData(typeof<TestEmptyVariants>)>]
25+
let ``TaskSeq-delay with empty sequences`` variant =
26+
fun () -> Gen.getEmptyVariant variant
27+
|> TaskSeq.delay
28+
|> verifyEmpty
29+
30+
module Immutable =
31+
[<Theory; ClassData(typeof<TestImmTaskSeq>)>]
32+
let ``TaskSeq-delay`` variant =
33+
fun () -> Gen.getSeqImmutable variant
34+
|> TaskSeq.delay
35+
|> validateSequence
36+
37+
module SideEffect =
38+
[<Fact>]
39+
let ``TaskSeq-delay executes side effects`` () = task {
40+
let mutable i = 0
41+
42+
let ts =
43+
fun () -> taskSeq {
44+
yield! [ 1..10 ]
45+
i <- i + 1
46+
}
47+
|> TaskSeq.delay
48+
49+
do! ts |> validateSequence
50+
i |> should equal 1
51+
let! len = TaskSeq.length ts
52+
i |> should equal 2 // re-eval of the sequence executes side effect again
53+
len |> should equal 10
54+
}

src/FSharp.Control.TaskSeq/TaskSeq.fs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ module TaskSeq =
164164
let initAsync count initializer = Internal.init (Some count) (InitActionAsync initializer)
165165
let initInfiniteAsync initializer = Internal.init None (InitActionAsync initializer)
166166

167+
let delay (generator: unit -> taskSeq<'T>) =
168+
{ new IAsyncEnumerable<'T> with
169+
member _.GetAsyncEnumerator(ct) = generator().GetAsyncEnumerator(ct)
170+
}
171+
167172
let concat (sources: taskSeq<#taskSeq<'T>>) = taskSeq {
168173
for ts in sources do
169174
yield! (ts :> taskSeq<'T>)

src/FSharp.Control.TaskSeq/TaskSeq.fsi

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ module TaskSeq =
3939
/// </summary>
4040
val lengthByAsync: predicate: ('T -> #Task<bool>) -> source: taskSeq<'T> -> Task<int>
4141

42+
/// <summary>
43+
/// Returns a task sequence that is given by the delayed specification of a task sequence.
44+
/// </summary>
45+
///
46+
/// <param name="generator">The generating function for the task sequence.</param>
47+
/// <returns>The generated task sequence.</returns>
48+
val delay: generator: (unit -> taskSeq<'T>) -> taskSeq<'T>
49+
4250
/// <summary>
4351
/// Generates a new task sequence which, when iterated, will return successive elements by calling the given function
4452
/// with the current index, up to the given count. Each element is saved after its initialization for successive access to

0 commit comments

Comments
 (0)