Skip to content

Commit 5fb32ec

Browse files
committed
Update readmes again
1 parent baa3eb0 commit 5fb32ec

File tree

2 files changed

+138
-22
lines changed

2 files changed

+138
-22
lines changed

README.md

Lines changed: 129 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
[![build][buildstatus_img]][buildstatus]
22
[![test][teststatus_img]][teststatus]
3+
[![Nuget](https://img.shields.io/nuget/vpre/FSharp.Control.TaskSeq)](https://www.nuget.org/packages/FSharp.Control.TaskSeq/)
34

45
# TaskSeq<!-- omit in toc -->
56

6-
An implementation [`IAsyncEnumerable<'T>`][3] as a `taskSeq` CE for F# with accompanying `TaskSeq` module.
7-
8-
The `IAsyncEnumerable` interface was added to .NET in `.NET Core 3.0` and is part of `.NET Standard 2.1`. The main use-case was for iterative asynchronous enumeration over some resource. For instance, an event stream or a REST API interface with pagination, where each page is a [`MoveNextAsync`][4] call on the [`IAsyncEnumerator<'T>`][5] given by a call to [`GetAsyncEnumerator()`][6]. It has been relatively challenging to work properly with this type and dealing with each step being asynchronous, and the enumerator implementing [`IAsyncDisposable`][7] as well, which requires careful handling.
7+
An implementation of [`IAsyncEnumerable<'T>`][3] as a computation expression: `taskSeq { ... }` with an accompanying `TaskSeq` module.
98

109
-----------------------------------------
1110

@@ -18,10 +17,15 @@ The `IAsyncEnumerable` interface was added to .NET in `.NET Core 3.0` and is par
1817
More info: https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one#table-of-contents
1918
-->
2019

21-
- [Feature planning](#feature-planning)
22-
- [Implementation progress](#implementation-progress)
23-
- [`taskSeq` CE](#taskseq-ce)
24-
- [`TaskSeq` module functions](#taskseq-module-functions)
20+
- [Overview](#overview)
21+
- [Module functions](#module-functions)
22+
- [`taskSeq` computation expressions](#taskseq-computation-expressions)
23+
- [Installation](#installation)
24+
- [Examples](#examples)
25+
- [Status & planning](#status--planning)
26+
- [Implementation progress](#implementation-progress)
27+
- [Progress `taskSeq` CE](#progress-taskseq-ce)
28+
- [Progress and implemented `TaskSeq` module functions](#progress-and-implemented-taskseq-module-functions)
2529
- [More information](#more-information)
2630
- [Futher reading `IAsyncEnumerable`](#futher-reading-iasyncenumerable)
2731
- [Futher reading on resumable state machines](#futher-reading-on-resumable-state-machines)
@@ -38,27 +42,134 @@ The `IAsyncEnumerable` interface was added to .NET in `.NET Core 3.0` and is par
3842

3943
-----------------------------------------
4044

41-
## Feature planning
45+
## Overview
46+
47+
The `IAsyncEnumerable` interface was added to .NET in `.NET Core 3.0` and is part of `.NET Standard 2.1`. The main use-case was for iterative asynchronous enumeration over some resource. For instance, an event stream or a REST API interface with pagination, asynchronous reading over a list of files and accumulating the results, where each action can be modeled as a [`MoveNextAsync`][4] call on the [`IAsyncEnumerator<'T>`][5] given by a call to [`GetAsyncEnumerator()`][6].
48+
49+
Since the introduction of `task` in F# the call for a native implementation of _task sequences_ has grown, in particular because proper iterating over an `IAsyncEnumerable` has proven challenging, especially if one wants to avoid mutable variables. This library is an answer to that call and implements the same _resumable state machine_ approach with `taskSeq`.
50+
51+
### Module functions
52+
53+
As with `seq` and `Seq`, this library comes with a bunch of well-known collection functions, like `TaskSeq.empty`, `isEmpty` or `TaskSeq.map`, `iter`, `collect`, `fold` and `TaskSeq.find`, `pick`, `choose`, `filter`. Where applicable, these come with async variants, like `TaskSeq.mapAsync` `iterAsync`, `collectAsync`, `foldAsync` and `TaskSeq.findAsync`, `pickAsync`, `chooseAsync`, `filterAsync`, which allows the applied function to be asynchronous.
54+
55+
[See below](#current-set-of-taskseq-utility-functions) for a full list of currently implemented functions and their variants.
56+
57+
### `taskSeq` computation expressions
58+
59+
The `taskSeq` computation expression can be used just like using `seq`. On top of that, it adds support for working with tasks through `let!` and
60+
looping over a normal or asynchronous sequence (one that implements `IAsyncEnumerable<'T>'`). You can use `yield!` and `yield` and there's support
61+
for `use` and `use!`, `try-with` and `try-finally` and `while` loops within the task sequence expression:
62+
63+
### Installation
4264

43-
Not necessarily in order of importance:
65+
Dotnet Nuget
66+
67+
```cmd
68+
dotnet add package FSharp.Control.TaskSeq
69+
```
70+
71+
For a specific project:
72+
73+
```cmd
74+
dotnet add myproject.fsproj package FSharp.Control.TaskSeq
75+
```
76+
77+
F# Interactive (FSI):
78+
79+
```f#
80+
// latest version
81+
> #r "nuget: FSharp.Control.TaskSeq"
82+
83+
// or with specific version
84+
> #r "nuget: FSharp.Control.TaskSeq, 0.2.2"
85+
```
86+
87+
Paket:
88+
89+
```cmd
90+
dotnet paket add FSharp.Control.TaskSeq --project <project>
91+
```
92+
93+
Package Manager:
94+
95+
```cmd
96+
PM> NuGet\Install-Package FSharp.Control.TaskSeq
97+
```
98+
99+
As package reference in `fsproj` or `csproj` file:
100+
101+
```xml
102+
<!-- replace version with most recent version -->
103+
<PackageReference Include="FSharp.Control.TaskSeq" Version="0.2.2" />
104+
```
105+
106+
### Examples
107+
108+
```f#
109+
open System.IO
110+
111+
open FSharp.Control
112+
113+
// singleton is fine
114+
let hello = taskSeq { yield "Hello, World!" }
115+
116+
// can be mixed with normal sequences
117+
let oneToTen = taskSeq { yield! [1..10] }
118+
119+
// returns a delayed sequence of IAsyncEnumerable<string>
120+
let allFilesAsLines() = taskSeq {
121+
let files = Directory.EnumerateFiles(@"c:\temp")
122+
for file in files do
123+
// await
124+
let! contents = File.ReadAllLinesAsync file
125+
// return all lines
126+
yield! contents
127+
}
128+
129+
let write file =
130+
allFilesAsLines()
131+
132+
// synchronous map function on asynchronous task sequence
133+
|> TaskSeq.map (fun x -> x.Replace("a", "b"))
134+
135+
// asynchronous map
136+
|> TaskSeq.mapAsync (fun x -> task { return "hello: " + x })
137+
138+
// asynchronous iter
139+
|> TaskSeq.iterAsync (fun data -> File.WriteAllTextAsync(fileName, data))
140+
141+
142+
// infinite sequence
143+
let feedFromTwitter user pwd = taskSeq {
144+
do! loginToTwitterAsync(user, pwd)
145+
while true do
146+
let! message = getNextNextTwitterMessageAsync()
147+
yield message
148+
}
149+
```
150+
151+
## Status & planning
152+
153+
This project has stable features currently, but before we go full "version one", we'd like to complete the surface area. This section covers the status of that, with a full list of implmented functions below. Here's the short list:
44154

45155
- [x] Stabilize and battle-test `taskSeq` resumable code. **DONE**
46156
- [x] A growing set of module functions `TaskSeq`, see below for progress. **DONE & IN PROGRESS**
47157
- [x] Packaging and publishing on Nuget, **DONE, PUBLISHED SINCE: 7 November 2022**. See https://www.nuget.org/packages/FSharp.Control.TaskSeq
48158
- [x] Add `Async` variants for functions taking HOF arguments. **DONE**
49159
- [ ] Add generated docs to <https://fsprojects.github.io>
50-
- [ ] Expand surface area based on `AsyncSeq`.
51-
- [ ] User requests?
160+
- [ ] Expand surface area based on `AsyncSeq`. **ONGOING**
161+
162+
### Implementation progress
52163

53-
## Implementation progress
164+
As of 9 November 2022: [Nuget package available][21]. In this phase, we will frequently update the package. Current:
54165

55-
As of 6 November 2022:
166+
[![Nuget](https://img.shields.io/nuget/vpre/FSharp.Control.TaskSeq)](https://www.nuget.org/packages/FSharp.Control.TaskSeq/)
56167

57-
### `taskSeq` CE
168+
### Progress `taskSeq` CE
58169

59-
The _resumable state machine_ backing the `taskSeq` CE is now finished and _restartability_ (not to be confused with _resumability_) has been implemented and stabilized. Full support for empty task sequences is done. Focus is now on adding functionality there, like adding more useful overloads for `yield` and `let!`. Suggestions are welcome!
170+
The _resumable state machine_ backing the `taskSeq` CE is now finished and _restartability_ (not to be confused with _resumability_) has been implemented and stabilized. Full support for empty task sequences is done. Focus is now on adding functionality there, like adding more useful overloads for `yield` and `let!`. [Suggestions are welcome!][issues].
60171

61-
### `TaskSeq` module functions
172+
### Progress and implemented `TaskSeq` module functions
62173

63174
We are working hard on getting a full set of module functions on `TaskSeq` that can be used with `IAsyncEnumerable` sequences. Our guide is the set of F# `Seq` functions in F# Core and, where applicable, the functions provided from `AsyncSeq`. Each implemented function is documented through XML doc comments to provide the necessary context-sensitive help.
64175

@@ -600,6 +711,7 @@ module TaskSeq =
600711
[18]: https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/computation-expressions
601712
[19]: https://fsharpforfunandprofit.com/series/computation-expressions/
602713
[20]: https://github.com/dotnet/fsharp/blob/d5312aae8aad650f0043f055bb14c3aa8117e12e/tests/benchmarks/CompiledCodeBenchmarks/TaskPerf/TaskPerf/taskSeq.fs
714+
[21]: https://www.nuget.org/packages/FSharp.Control.TaskSeq#versions-body-tab
603715

604716
[#2]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/2
605717
[#11]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/11
@@ -614,3 +726,4 @@ module TaskSeq =
614726
[#82]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/82
615727
[#83]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/83
616728

729+
[issues]: https://github.com/fsprojects/FSharp.Control.TaskSeq/issues

assets/nuget-package-readme.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ An implementation of [`IAsyncEnumerable<'T>`][3] as a computation expression: `t
1414
-->
1515

1616
- [Overview](#overview)
17+
- [Module functions](#module-functions)
1718
- [`taskSeq` computation expressions](#taskseq-computation-expressions)
1819
- [Examples](#examples)
1920
- [`TaskSeq` module functions](#taskseq-module-functions)
@@ -26,19 +27,21 @@ An implementation of [`IAsyncEnumerable<'T>`][3] as a computation expression: `t
2627

2728
## Overview
2829

29-
The `IAsyncEnumerable` interface was added to .NET in `.NET Core 3.0` and is part of `.NET Standard 2.1`. The main use-case was for iterative asynchronous enumeration over some resource. For instance, an event stream or a REST API interface with pagination, asynchronous reading over a list of files and accumulating the results, where each action can be modeled as a [`MoveNextAsync`][4] call on the [`IAsyncEnumerator<'T>`][5] given by a call to [`GetAsyncEnumerator()`][6].
30+
The `IAsyncEnumerable` interface was added to .NET in `.NET Core 3.0` and is part of `.NET Standard 2.1`. The main use-case was for iterative asynchronous enumeration over some resource. For instance, an event stream or a REST API interface with pagination, asynchronous reading over a list of files and accumulating the results, where each action can be modeled as a [`MoveNextAsync`][4] call on the [`IAsyncEnumerator<'T>`][5] given by a call to [`GetAsyncEnumerator()`][6].
3031

3132
Since the introduction of `task` in F# the call for a native implementation of _task sequences_ has grown, in particular because proper iterating over an `IAsyncEnumerable` has proven challenging, especially if one wants to avoid mutable variables. This library is an answer to that call and implements the same _resumable state machine_ approach with `taskSeq`.
3233

33-
As with `seq` and `Seq`, this library comes with a bunch of well-known collection functions, like `TaskSeq.empty/isEmpty` or `TaskSeq.map/iter/collect` and `TaskSeq.find/pick/choose/filter`. Where applicable, these come with async variants, like `TaskSeq.mapAsync/iterAsync/collectAsync` and `TaskSeq.findAsync/pickAsync/chooseAsync/filterAsync`, which allows the apply function to be asynchronous.
34+
### Module functions
3435

35-
See below for a full list of currently implemented functions.
36+
As with `seq` and `Seq`, this library comes with a bunch of well-known collection functions, like `TaskSeq.empty`, `isEmpty` or `TaskSeq.map`, `iter`, `collect`, `fold` and `TaskSeq.find`, `pick`, `choose`, `filter`. Where applicable, these come with async variants, like `TaskSeq.mapAsync` `iterAsync`, `collectAsync`, `foldAsync` and `TaskSeq.findAsync`, `pickAsync`, `chooseAsync`, `filterAsync`, which allows the applied function to be asynchronous.
37+
38+
[See below](#taskseq-module-functions) for a full list of currently implemented functions and their variants.
3639

3740
### `taskSeq` computation expressions
3841

39-
The `taskSeq` computation expression can be used just like using `seq`. On top of that, it adds support for working with tasks through `let!` and
42+
The `taskSeq` computation expression can be used just like using `seq`. On top of that, it adds support for working with tasks through `let!` and
4043
looping over a normal or asynchronous sequence (one that implements `IAsyncEnumerable<'T>'`). You can use `yield!` and `yield` and there's support
41-
for `use` and `use!`, `try-with` and `try-finally` and `while` loops within the task sequence expression:
44+
for `use` and `use!`, `try-with` and `try-finally` and `while` loops within the task sequence expression.
4245

4346
### Examples
4447

@@ -48,7 +51,7 @@ open System.IO
4851
open FSharp.Control
4952
5053
// singleton is fine
51-
let hello = taskSeq { yield "Hello, World!"" }
54+
let hello = taskSeq { yield "Hello, World!" }
5255
5356
// can be mixed with normal sequences
5457
let oneToTen = taskSeq { yield! [1..10] }

0 commit comments

Comments
 (0)