From 6cde169d451e469361250b23d5f82a5f19dee278 Mon Sep 17 00:00:00 2001 From: Abel Braaksma Date: Thu, 21 Dec 2023 00:33:45 +0100 Subject: [PATCH] Also update the nuget readme, which differs significantly --- assets/nuget-package-readme.md | 282 +++++++++++++++++---------------- 1 file changed, 145 insertions(+), 137 deletions(-) diff --git a/assets/nuget-package-readme.md b/assets/nuget-package-readme.md index 35e6320c..751258bc 100644 --- a/assets/nuget-package-readme.md +++ b/assets/nuget-package-readme.md @@ -56,7 +56,7 @@ let helloTs = taskSeq { yield "Hello, World!" } let f() = task { // using toList forces execution of whole sequence let! hello = TaskSeq.toList helloTs // toList returns a Task<'T list> - return List.head hello + return List.head hello } // can be mixed with normal sequences @@ -76,15 +76,15 @@ let allFilesAsLines() = taskSeq { yield! contents } -let write file = +let write file = allFilesAsLines() - + // synchronous map function on asynchronous task sequence |> TaskSeq.map (fun x -> x.Replace("a", "b")) // asynchronous map |> TaskSeq.mapAsync (fun x -> task { return "hello: " + x }) - + // asynchronous iter |> TaskSeq.iterAsync (fun data -> File.WriteAllTextAsync(fileName, data)) @@ -102,144 +102,149 @@ let feedFromTwitter user pwd = taskSeq { 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. -The following is the progress report: - -| Done | `Seq` | `TaskSeq` | Variants | Remarks | -|------------------|--------------------|-----------------|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| ❓ | `allPairs` | `allPairs` | | [note #1](#note-1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | -| ✅ [#81][] | `append` | `append` | | | -| ✅ [#81][] | | | `appendSeq` | | -| ✅ [#81][] | | | `prependSeq` | | -| | `average` | `average` | | | -| | `averageBy` | `averageBy` | `averageByAsync` | | -| ❓ | `cache` | `cache` | | [note #1](#note-1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | -| ✅ [#67][] | `cast` | `cast` | | | -| ✅ [#67][] | | | `box` | | -| ✅ [#67][] | | | `unbox` | | -| ✅ [#23][] | `choose` | `choose` | `chooseAsync` | | -| | `chunkBySize` | `chunkBySize` | | | -| ✅ [#11][] | `collect` | `collect` | `collectAsync` | | -| ✅ [#11][] | | `collectSeq` | `collectSeqAsync` | | -| | `compareWith` | `compareWith` | `compareWithAsync` | | -| ✅ [#69][] | `concat` | `concat` | | | -| ✅ [#70][] | `contains` | `contains` | | | -| ✅ [#82][] | `delay` | `delay` | | | -| | `distinct` | `distinct` | | | -| | `distinctBy` | `dictinctBy` | `distinctByAsync` | | -| ✅ [#2][] | `empty` | `empty` | | | -| ✅ [#23][] | `exactlyOne` | `exactlyOne` | | | -| ✅ [#83][] | `except` | `except` | | | -| ✅ [#83][] | | `exceptOfSeq` | | | -| ✅ [#70][] | `exists` | `exists` | `existsAsync` | | -| | `exists2` | `exists2` | | | -| ✅ [#23][] | `filter` | `filter` | `filterAsync` | | -| ✅ [#23][] | `find` | `find` | `findAsync` | | -| 🚫 | `findBack` | | | [note #2](#note-2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | -| ✅ [#68][] | `findIndex` | `findIndex` | `findIndexAsync` | | -| 🚫 | `findIndexBack` | n/a | n/a | [note #2](#note-2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | -| ✅ [#2][] | `fold` | `fold` | `foldAsync` | | -| | `fold2` | `fold2` | `fold2Async` | | -| 🚫 | `foldBack` | | | [note #2](#note-2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | -| 🚫 | `foldBack2` | | | [note #2](#note-2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | -| | `forall` | `forall` | `forallAsync` | | -| | `forall2` | `forall2` | `forall2Async` | | -| ❓ | `groupBy` | `groupBy` | `groupByAsync` | [note #1](#note-1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | -| ✅ [#23][] | `head` | `head` | | | -| ✅ [#68][] | `indexed` | `indexed` | | | -| ✅ [#69][] | `init` | `init` | `initAsync` | | -| ✅ [#69][] | `initInfinite` | `initInfinite` | `initInfiniteAsync` | | -| | `insertAt` | `insertAt` | | | -| | `insertManyAt` | `insertManyAt` | | | -| ✅ [#23][] | `isEmpty` | `isEmpty` | | | -| ✅ [#23][] | `item` | `item` | | | -| ✅ [#2][] | `iter` | `iter` | `iterAsync` | | -| | `iter2` | `iter2` | `iter2Async` | | -| ✅ [#2][] | `iteri` | `iteri` | `iteriAsync` | | -| | `iteri2` | `iteri2` | `iteri2Async` | | -| ✅ [#23][] | `last` | `last` | | | -| ✅ [#53][] | `length` | `length` | | | -| ✅ [#53][] | | `lengthBy` | `lengthByAsync` | | -| ✅ [#2][] | `map` | `map` | `mapAsync` | | -| | `map2` | `map2` | `map2Async` | | -| | `map3` | `map3` | `map3Async` | | -| | `mapFold` | `mapFold` | `mapFoldAsync` | | -| 🚫 | `mapFoldBack` | | | [note #2](#note-2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | -| ✅ [#2][] | `mapi` | `mapi` | `mapiAsync` | | -| | `mapi2` | `mapi2` | `mapi2Async` | | -| | `max` | `max` | | | -| | `maxBy` | `maxBy` | `maxByAsync` | | -| | `min` | `min` | | | -| | `minBy` | `minBy` | `minByAsync` | | -| ✅ [#2][] | `ofArray` | `ofArray` | | | -| ✅ [#2][] | | `ofAsyncArray` | | | -| ✅ [#2][] | | `ofAsyncList` | | | -| ✅ [#2][] | | `ofAsyncSeq` | | | -| ✅ [#2][] | `ofList` | `ofList` | | | -| ✅ [#2][] | | `ofTaskList` | | | -| ✅ [#2][] | | `ofResizeArray` | | | -| ✅ [#2][] | | `ofSeq` | | | -| ✅ [#2][] | | `ofTaskArray` | | | -| ✅ [#2][] | | `ofTaskList` | | | -| ✅ [#2][] | | `ofTaskSeq` | | | -| | `pairwise` | `pairwise` | | | -| | `permute` | `permute` | `permuteAsync` | | -| ✅ [#23][] | `pick` | `pick` | `pickAsync` | | -| 🚫 | `readOnly` | | | [note #3](#note-3 "The motivation for 'readOnly' in 'Seq' is that a cast from a mutable array or list to a 'seq<_>' is valid and can be cast back, leading to a mutable sequence. Since 'TaskSeq' doesn't implement 'IEnumerable<_>', such casts are not possible.") | -| | `reduce` | `reduce` | `reduceAsync` | | -| 🚫 | `reduceBack` | | | [note #2](#note-2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | -| | `removeAt` | `removeAt` | | | -| | `removeManyAt` | `removeManyAt` | | | -| | `replicate` | `replicate` | | | -| ❓ | `rev` | | | [note #1](#note-1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | -| | `scan` | `scan` | `scanAsync` | | -| 🚫 | `scanBack` | | | [note #2](#note-2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | -| ✅ [#90][] | `singleton` | `singleton` | | | -| | `skip` | `skip` | | | -| | `skipWhile` | `skipWhile` | `skipWhileAsync` | | -| ❓ | `sort` | | | [note #1](#note-1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | -| ❓ | `sortBy` | | | [note #1](#note-1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | -| ❓ | `sortByAscending` | | | [note #1](#note-1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | -| ❓ | `sortByDescending` | | | [note #1](#note-1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | -| ❓ | `sortWith` | | | [note #1](#note-1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | -| | `splitInto` | `splitInto` | | | -| | `sum` | `sum` | | | -| | `sumBy` | `sumBy` | `sumByAsync` | | -| ✅ [#76][] | `tail` | `tail` | | | -| | `take` | `take` | | | -| | `takeWhile` | `takeWhile` | `takeWhileAsync` | | -| ✅ [#2][] | `toArray` | `toArray` | `toArrayAsync` | | -| ✅ [#2][] | | `toIList` | `toIListAsync` | | -| ✅ [#2][] | `toList` | `toList` | `toListAsync` | | -| ✅ [#2][] | | `toResizeArray` | `toResizeArrayAsync` | | -| ✅ [#2][] | | `toSeq` | `toSeqAsync` | | -| | | […] | | | -| ❓ | `transpose` | | | [note #1](#note-1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | -| | `truncate` | `truncate` | | | -| ✅ [#23][] | `tryExactlyOne` | `tryExactlyOne` | `tryExactlyOneAsync` | | -| ✅ [#23][] | `tryFind` | `tryFind` | `tryFindAsync` | | -| 🚫 | `tryFindBack` | | | [note #2](#note-2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | -| ✅ [#68][] | `tryFindIndex` | `tryFindIndex` | `tryFindIndexAsync` | | -| 🚫 | `tryFindIndexBack` | | | [note #2](#note-2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | -| ✅ [#23][] | `tryHead` | `tryHead` | | | -| ✅ [#23][] | `tryItem` | `tryItem` | | | -| ✅ [#23][] | `tryLast` | `tryLast` | | | -| ✅ [#23][] | `tryPick` | `tryPick` | `tryPickAsync` | | -| ✅ [#76][] | | `tryTail` | | | -| | `unfold` | `unfold` | `unfoldAsync` | | -| | `updateAt` | `updateAt` | | | -| | `where` | `where` | `whereAsync` | | -| | `windowed` | `windowed` | | | -| ✅ [#2][] | `zip` | `zip` | | | -| | `zip3` | `zip3` | | | -| | | `zip4` | | | +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 by `AsyncSeq`. Each implemented function is documented through XML doc comments to provide the necessary context-sensitive help. + +This is what was implemented, planned or skipped: + +| Done | `Seq` | `TaskSeq` | Variants | Remarks | +|------------------|--------------------|----------------------|---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ❓ | `allPairs` | `allPairs` | | [note #1](#note1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | +| ✅ [#81][] | `append` | `append` | | | +| ✅ [#81][] | | | `appendSeq` | | +| ✅ [#81][] | | | `prependSeq` | | +| | `average` | `average` | | | +| | `averageBy` | `averageBy` | `averageByAsync` | | +| ❓ | `cache` | `cache` | | [note #1](#note1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | +| ✅ [#67][] | `cast` | `cast` | | | +| ✅ [#67][] | | | `box` | | +| ✅ [#67][] | | | `unbox` | | +| ✅ [#23][] | `choose` | `choose` | `chooseAsync` | | +| | `chunkBySize` | `chunkBySize` | | | +| ✅ [#11][] | `collect` | `collect` | `collectAsync` | | +| ✅ [#11][] | | `collectSeq` | `collectSeqAsync` | | +| | `compareWith` | `compareWith` | `compareWithAsync` | | +| ✅ [#69][] | `concat` | `concat` | | | +| ✅ [#70][] | `contains` | `contains` | | | +| ✅ [#82][] | `delay` | `delay` | | | +| | `distinct` | `distinct` | | | +| | `distinctBy` | `dictinctBy` | `distinctByAsync` | | +| ✅ [#2][] | `empty` | `empty` | | | +| ✅ [#23][] | `exactlyOne` | `exactlyOne` | | | +| ✅ [#83][] | `except` | `except` | | | +| ✅ [#83][] | | `exceptOfSeq` | | | +| ✅ [#70][] | `exists` | `exists` | `existsAsync` | | +| | `exists2` | `exists2` | | | +| ✅ [#23][] | `filter` | `filter` | `filterAsync` | | +| ✅ [#23][] | `find` | `find` | `findAsync` | | +| 🚫 | `findBack` | | | [note #2](#note2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | +| ✅ [#68][] | `findIndex` | `findIndex` | `findIndexAsync` | | +| 🚫 | `findIndexBack` | n/a | n/a | [note #2](#note2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | +| ✅ [#2][] | `fold` | `fold` | `foldAsync` | | +| | `fold2` | `fold2` | `fold2Async` | | +| 🚫 | `foldBack` | | | [note #2](#note2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | +| 🚫 | `foldBack2` | | | [note #2](#note2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | +| | `forall` | `forall` | `forallAsync` | | +| | `forall2` | `forall2` | `forall2Async` | | +| ❓ | `groupBy` | `groupBy` | `groupByAsync` | [note #1](#note1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | +| ✅ [#23][] | `head` | `head` | | | +| ✅ [#68][] | `indexed` | `indexed` | | | +| ✅ [#69][] | `init` | `init` | `initAsync` | | +| ✅ [#69][] | `initInfinite` | `initInfinite` | `initInfiniteAsync` | | +| | `insertAt` | `insertAt` | | | +| | `insertManyAt` | `insertManyAt` | | | +| ✅ [#23][] | `isEmpty` | `isEmpty` | | | +| ✅ [#23][] | `item` | `item` | | | +| ✅ [#2][] | `iter` | `iter` | `iterAsync` | | +| | `iter2` | `iter2` | `iter2Async` | | +| ✅ [#2][] | `iteri` | `iteri` | `iteriAsync` | | +| | `iteri2` | `iteri2` | `iteri2Async` | | +| ✅ [#23][] | `last` | `last` | | | +| ✅ [#53][] | `length` | `length` | | | +| ✅ [#53][] | | `lengthBy` | `lengthByAsync` | | +| ✅ [#2][] | `map` | `map` | `mapAsync` | | +| | `map2` | `map2` | `map2Async` | | +| | `map3` | `map3` | `map3Async` | | +| | `mapFold` | `mapFold` | `mapFoldAsync` | | +| 🚫 | `mapFoldBack` | | | [note #2](#note2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | +| ✅ [#2][] | `mapi` | `mapi` | `mapiAsync` | | +| | `mapi2` | `mapi2` | `mapi2Async` | | +| | `max` | `max` | | | +| | `maxBy` | `maxBy` | `maxByAsync` | | +| | `min` | `min` | | | +| | `minBy` | `minBy` | `minByAsync` | | +| ✅ [#2][] | `ofArray` | `ofArray` | | | +| ✅ [#2][] | | `ofAsyncArray` | | | +| ✅ [#2][] | | `ofAsyncList` | | | +| ✅ [#2][] | | `ofAsyncSeq` | | | +| ✅ [#2][] | `ofList` | `ofList` | | | +| ✅ [#2][] | | `ofTaskList` | | | +| ✅ [#2][] | | `ofResizeArray` | | | +| ✅ [#2][] | | `ofSeq` | | | +| ✅ [#2][] | | `ofTaskArray` | | | +| ✅ [#2][] | | `ofTaskList` | | | +| ✅ [#2][] | | `ofTaskSeq` | | | +| | `pairwise` | `pairwise` | | | +| | `permute` | `permute` | `permuteAsync` | | +| ✅ [#23][] | `pick` | `pick` | `pickAsync` | | +| 🚫 | `readOnly` | | | [note #3](#note3 "The motivation for 'readOnly' in 'Seq' is that a cast from a mutable array or list to a 'seq<_>' is valid and can be cast back, leading to a mutable sequence. Since 'TaskSeq' doesn't implement 'IEnumerable<_>', such casts are not possible.") | +| | `reduce` | `reduce` | `reduceAsync` | | +| 🚫 | `reduceBack` | | | [note #2](#note2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | +| | `removeAt` | `removeAt` | | | +| | `removeManyAt` | `removeManyAt` | | | +| | `replicate` | `replicate` | | | +| ❓ | `rev` | | | [note #1](#note1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | +| | `scan` | `scan` | `scanAsync` | | +| 🚫 | `scanBack` | | | [note #2](#note2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | +| ✅ [#90][] | `singleton` | `singleton` | | | +| ✅ [#209][]| `skip` | `skip` | | | +| ✅ [#209][]| | `drop` | | | +| | `skipWhile` | `skipWhile` | `skipWhileAsync` | | +| | | `skipWhileInclusive` | `skipWhileInclusiveAsync` | | +| ❓ | `sort` | | | [note #1](#note1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | +| ❓ | `sortBy` | | | [note #1](#note1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | +| ❓ | `sortByAscending` | | | [note #1](#note1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | +| ❓ | `sortByDescending` | | | [note #1](#note1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | +| ❓ | `sortWith` | | | [note #1](#note1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | +| | `splitInto` | `splitInto` | | | +| | `sum` | `sum` | | | +| | `sumBy` | `sumBy` | `sumByAsync` | | +| ✅ [#76][] | `tail` | `tail` | | | +| ✅ [#209][]| `take` | `take` | | | +| ✅ [#126][]| `takeWhile` | `takeWhile` | `takeWhileAsync` | | +| ✅ [#126][]| | `takeWhileInclusive` | `takeWhileInclusiveAsync` | | +| ✅ [#2][] | `toArray` | `toArray` | `toArrayAsync` | | +| ✅ [#2][] | | `toIList` | `toIListAsync` | | +| ✅ [#2][] | `toList` | `toList` | `toListAsync` | | +| ✅ [#2][] | | `toResizeArray` | `toResizeArrayAsync` | | +| ✅ [#2][] | | `toSeq` | `toSeqAsync` | | +| | | […] | | | +| ❓ | `transpose` | | | [note #1](#note1 "These functions require a form of pre-materializing through 'TaskSeq.cache', similar to the approach taken in the corresponding 'Seq' functions. It doesn't make much sense to have a cached async sequence. However, 'AsyncSeq' does implement these, so we'll probably do so eventually as well.") | +| ✅ [#209][]| `truncate` | `truncate` | | | +| ✅ [#23][] | `tryExactlyOne` | `tryExactlyOne` | `tryExactlyOneAsync` | | +| ✅ [#23][] | `tryFind` | `tryFind` | `tryFindAsync` | | +| 🚫 | `tryFindBack` | | | [note #2](#note2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | +| ✅ [#68][] | `tryFindIndex` | `tryFindIndex` | `tryFindIndexAsync` | | +| 🚫 | `tryFindIndexBack` | | | [note #2](#note2 "Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the 'Back' iterators.") | +| ✅ [#23][] | `tryHead` | `tryHead` | | | +| ✅ [#23][] | `tryItem` | `tryItem` | | | +| ✅ [#23][] | `tryLast` | `tryLast` | | | +| ✅ [#23][] | `tryPick` | `tryPick` | `tryPickAsync` | | +| ✅ [#76][] | | `tryTail` | | | +| | `unfold` | `unfold` | `unfoldAsync` | | +| | `updateAt` | `updateAt` | | | +| | `where` | `where` | `whereAsync` | | +| | `windowed` | `windowed` | | | +| ✅ [#2][] | `zip` | `zip` | | | +| | `zip3` | `zip3` | | | +| | | `zip4` | | | #### Note 1 -_These functions require a form of pre-materializing through `TaskSeq.cache`, similar to the approach taken in the corresponding `Seq` functions. It doesn't make much sense to have a cached async sequence. However, `AsyncSeq` does implement these, so we'll probably do so eventually as well._ +_These functions require a form of pre-materializing through `TaskSeq.cache`, similar to the approach taken in the corresponding `Seq` functions. It doesn't make much sense to have a cached async sequence. However, `AsyncSeq` does implement these, so we'll probably do so eventually as well._ #### Note 2 -_Because of the async nature of `TaskSeq` sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the `xxxBack` iterators._ +_Because of the async nature of `TaskSeq` sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the `xxxBack` iterators._ #### Note 3 @@ -297,4 +302,7 @@ _The motivation for `readOnly` in `Seq` is that a cast from a mutable array or l [#81]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/81 [#82]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/82 [#83]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/83 -[#90]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/90 \ No newline at end of file +[#90]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/90 +[#126]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/126 +[#133]: https://github.com/fsprojects/FSharp.Control.TaskSeq/issues/133 +[#209]: https://github.com/fsprojects/FSharp.Control.TaskSeq/issues/209 \ No newline at end of file