Skip to content

Commit 5f0d5dd

Browse files
committed
Add TaskSeq.insertAt and TaskSeq.insertManyAt
1 parent 988ac7f commit 5f0d5dd

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

src/FSharp.Control.TaskSeq/TaskSeq.fs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,9 @@ type TaskSeq private () =
315315
static member tryFindIndex predicate source = Internal.tryFindIndex (Predicate predicate) source
316316
static member tryFindIndexAsync predicate source = Internal.tryFindIndex (PredicateAsync predicate) source
317317

318+
static member insertAt index value source = Internal.insertAt index (One value) source
319+
static member insertManyAt index values source = Internal.insertAt index (Many values) source
320+
318321
static member except itemsToExclude source = Internal.except itemsToExclude source
319322
static member exceptOfSeq itemsToExclude source = Internal.exceptOfSeq itemsToExclude source
320323

src/FSharp.Control.TaskSeq/TaskSeq.fsi

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,7 @@ type TaskSeq =
12411241
///
12421242
/// <param name="source1">The first input task sequence.</param>
12431243
/// <param name="source2">The second input task sequence.</param>
1244+
/// <returns>The result task sequence of tuples.</returns>
12441245
/// <exception cref="T:ArgumentNullException">Thrown when either of the two input task sequences is null.</exception>
12451246
static member zip: source1: TaskSeq<'T> -> source2: TaskSeq<'U> -> TaskSeq<'T * 'U>
12461247

@@ -1275,3 +1276,27 @@ type TaskSeq =
12751276
/// <exception cref="T:ArgumentNullException">Thrown when the input task sequence is null.</exception>
12761277
static member foldAsync:
12771278
folder: ('State -> 'T -> #Task<'State>) -> state: 'State -> source: TaskSeq<'T> -> Task<'State>
1279+
1280+
/// <summary>
1281+
/// Return a new task sequence with a new item inserted before the given index.
1282+
/// </summary>
1283+
///
1284+
/// <param name="index">The index where the item should be inserted.</param>
1285+
/// <param name="value">The value to insert.</param>
1286+
/// <param name="source">The input task sequence.</param>
1287+
/// <returns>The result task sequence.</returns>
1288+
/// <exception cref="T:ArgumentNullException">Thrown when the input task sequence is null.</exception>
1289+
/// <exception cref="T:ArgumentException">Thrown when index is below 0 or greater than source length.</exception>
1290+
static member insertAt: index: int -> value: 'T -> source: TaskSeq<'T> -> TaskSeq<'T>
1291+
1292+
/// <summary>
1293+
/// Return a new task sequence with the new items inserted before the given index.
1294+
/// </summary>
1295+
///
1296+
/// <param name="index">The index where the items should be inserted.</param>
1297+
/// <param name="value">The values to insert.</param>
1298+
/// <param name="source">The input task sequence.</param>
1299+
/// <returns>The result task sequence.</returns>
1300+
/// <exception cref="T:ArgumentNullException">Thrown when the input task sequence is null.</exception>
1301+
/// <exception cref="T:ArgumentException">Thrown when index is below 0 or greater than source length.</exception>
1302+
static member insertManyAt: index: int -> values: TaskSeq<'T> -> source: TaskSeq<'T> -> TaskSeq<'T>

src/FSharp.Control.TaskSeq/TaskSeqInternal.fs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ type internal InitAction<'T, 'TaskT when 'TaskT :> Task<'T>> =
4949
| InitAction of init_item: (int -> 'T)
5050
| InitActionAsync of async_init_item: (int -> 'TaskT)
5151

52+
[<Struct>]
53+
type internal ManyOrOne<'T> =
54+
| Many of source_seq: TaskSeq<'T>
55+
| One of source_item: 'T
56+
5257
module internal TaskSeqInternal =
5358
/// Raise an NRE for arguments that are null. Only used for 'source' parameters, never for function parameters.
5459
let inline checkNonNull argName arg =
@@ -861,6 +866,33 @@ module internal TaskSeqInternal =
861866
yield e.Current
862867
}
863868

869+
/// InsertAt or InsertManyAt
870+
let insertAt index valueOrValues (source: TaskSeq<_>) =
871+
if index < 0 then
872+
invalidArg "index" "index cannot be negative."
873+
874+
taskSeq {
875+
let mutable i = 0
876+
877+
for item in source do
878+
if i = index then
879+
match valueOrValues with
880+
| Many values -> yield! values
881+
| One value -> yield value
882+
883+
yield item
884+
i <- i + 1
885+
886+
// allow inserting at the end
887+
if i = index then
888+
match valueOrValues with
889+
| Many values -> yield! values
890+
| One value -> yield value
891+
892+
if i < index then
893+
invalidArg "index" "index must be within the bounds of the task sequence."
894+
}
895+
864896
// Consider turning using an F# version of this instead?
865897
// https://github.com/i3arnon/ConcurrentHashSet
866898
type ConcurrentHashSet<'T when 'T: equality>(ct) =

0 commit comments

Comments
 (0)