diff --git a/src/FSharpPlus/Data/NonEmptySeq.fs b/src/FSharpPlus/Data/NonEmptySeq.fs
index 3a29e8524..d02dea965 100644
--- a/src/FSharpPlus/Data/NonEmptySeq.fs
+++ b/src/FSharpPlus/Data/NonEmptySeq.fs
@@ -77,6 +77,18 @@ module NonEmptySeq =
let appendSeqBack (seq: _ seq) (source: _ NonEmptySeq) =
Seq.append seq source |> unsafeOfSeq
+ /// Returns the average of the elements in the list.
+ /// The input list.
+ /// The resulting average.
+ let inline average (list: NonEmptySeq<'T>) = Seq.average list
+
+ /// Returns the average of the elements generated by applying the function to each element of the list.
+ /// The function to transform the list elements into the type to be averaged.
+ /// The input list.
+ /// The resulting average.
+ let inline averageBy (projection: 'T -> ^U) (list: NonEmptySeq<'T>) =
+ Seq.averageBy projection list
+
/// Returns a sequence that corresponds to a cached version of the input sequence.
/// This result sequence will have the same elements as the input sequence. The result
/// can be enumerated multiple times. The input sequence will be enumerated at most
@@ -103,7 +115,37 @@ module NonEmptySeq =
///
/// The result sequence.
let cache (source: _ NonEmptySeq) = Seq.cache source |> unsafeOfSeq
+
+ /// Wraps a loosely-typed System.Collections sequence as a typed sequence.
+ /// The input sequence.
+ /// The result sequence.
+ /// Thrown when the input sequence is null.
+ let cast (source: _ NonEmptySeq) = Seq.cast source |> unsafeOfSeq
+ ///
+ /// Applies a function to each element in a list and then returns a list of values v where the applied function returned Some(v).
+ ///
+ /// The function to be applied to the list elements.
+ /// The input sequence.
+ /// The resulting list comprising the values v where the chooser function returned Some(x).
+ let inline choose chooser (source: NonEmptySeq<'T>) = source |> Seq.choose chooser |> unsafeOfSeq
+
+ ///
+ /// Applies a function to each element in a list and then returns a list of values v where the applied function returned Some(v).
+ ///
+ /// The function to be applied to the list elements.
+ /// The input sequence.
+ /// The resulting list comprising the values v where the chooser function returned Some(x).
+ let inline tryChoose chooser (source: NonEmptySeq<'T>) = source |> Seq.choose chooser |> List.ofSeq
+
+ /// Divides the input list into lists (chunks) of size at most chunkSize.
+ /// Returns a new list containing the generated lists (chunks) as its elements.
+ /// The maximum size of each chunk.
+ /// The input sequence.
+ /// The sequence divided into chunks.
+ let inline chunkBySize chunkSize (source: NonEmptySeq<'T>) =
+ source |> Seq.chunkBySize chunkSize |> Seq.map unsafeOfSeq
+
/// Applies the given function to each element of the sequence and concatenates all the
/// results.
///
@@ -116,6 +158,26 @@ module NonEmptySeq =
/// The result sequence.
let collect (mapping: 'a -> '``#NonEmptySeq<'b>``) (source: NonEmptySeq<'a>) : NonEmptySeq<'b> when '``#NonEmptySeq<'b>`` :> NonEmptySeq<'b> =
Seq.collect mapping source |> unsafeOfSeq
+
+ /// For each element of the list, applies the given function.
+ /// Concatenates all the results and returns the combined list.
+ /// The function to transform each input element into a sublist to be concatenated.
+ /// The input sequence.
+ /// The concatenation of the transformed sublists.
+ let tryCollect (mapping: 'a -> #seq<'b>) (source: NonEmptySeq<'a>) : seq<'b> =
+ source |> Seq.collect mapping
+
+ /// Compares two sequences using the given comparison function, element by element.
+ /// A function that takes an element from each sequence and returns an int. If it evaluates to a non-zero value iteration is stopped and that value is returned.
+ /// The first input sequence.
+ /// The second input sequence.
+ /// Returns the first non-zero result from the comparison function.
+ /// If the first sequence has a larger element, the return value is always positive.
+ /// If the second sequence has a larger element, the return value is always negative.
+ /// When the elements are equal in the two sequences, 1 is returned if the first sequence is longer, 0 is returned if they are equal in length, and -1 is returned when the second list is longer.
+ ///
+ let compareWith comparer (source1: NonEmptySeq<'T>) (source2: NonEmptySeq<'T>) =
+ Seq.compareWith comparer source1 source2
/// Combines the given enumeration-of-enumerations as a single concatenated
/// enumeration.
@@ -129,6 +191,24 @@ module NonEmptySeq =
let concat (sources: NonEmptySeq<'``#NonEmptySeq<'a>``>) : NonEmptySeq<'a> when '``#NonEmptySeq<'a>`` :> NonEmptySeq<'a> =
Seq.concat sources |> unsafeOfSeq
+ /// Returns a new list that contains the elements of each of the lists in order.
+ /// Returns None if all of the inner lists are empty.
+ /// The input list of lists.
+ /// The resulting concatenated list or None.
+ let inline tryConcat (sources: NonEmptySeq<#seq<'T>>) = sources |> Seq.concat |> unsafeOfSeq
+
+ /// Tests if the sequence contains the specified element.
+ /// The value to locate in the input sequence.
+ /// The input sequence.
+ /// True if the input sequence contains the specified element; false otherwise.
+ let inline contains (value: 'T) (source: NonEmptySeq<'T>) = Seq.contains value source
+
+ /// Applies a key-generating function to each element of a sequence and returns a sequence yielding unique keys and their number of occurrences in the original list.
+ /// A function transforming each item of the input sequence into a key to be compared against the others.
+ /// The input sequence.
+ /// The resulting sequence of unique keys and their number of occurrences.
+ let inline countBy (projection: 'T -> 'U) (source: NonEmptySeq<'T>) = Seq.countBy projection source
+
/// Returns a sequence that is built from the given delayed specification of a
/// sequence.
///
@@ -138,6 +218,164 @@ module NonEmptySeq =
/// The generating function for the sequence.
let delay (generator: unit -> NonEmptySeq<'a>) : NonEmptySeq<'a> = Seq.delay (fun () -> generator () :> _) |> unsafeOfSeq
+ /// Returns a sequence that contains no duplicate entries according to the generic hash and equality comparisons
+ /// on the keys returned by the given key-generating function.
+ /// If an element occurs multiple times in the sequence then the later occurrences are discarded.
+ /// The input sequence.
+ /// The resulting sequence without duplicates.
+ let distinct (source: NonEmptySeq<'T>) = source |> Seq.distinct |> unsafeOfSeq
+
+ /// Returns a sequence that contains no duplicate entries according to the generic hash and equality comparisons on the keys returned by the given key-generating function.
+ /// If an element occurs multiple times in the sequence then the later occurrences are discarded.
+ /// A function transforming the sequence items into comparable keys.
+ /// The input sequence.
+ /// The resulting sequence.
+ let inline distinctBy (projection: 'T -> 'U) (source: NonEmptySeq<'T>) = Seq.distinctBy projection source |> unsafeOfSeq
+
+ /// Returns the only element of the sequence.
+ /// The input sequence.
+ /// The only element of the sequence.
+ /// Thrown when the input does not have precisely one element.
+ let inline exactlyOne (source: NonEmptySeq<'T>) = Seq.exactlyOne source
+
+ /// Returns a new sequence with the distinct elements of the input sequence which do not appear in the itemsToExclude sequence, using generic hash and equality comparisons to compare values.
+ /// The sequence of items to exclude from the input sequence.
+ /// The input sequence.
+ /// A sequence that contains the distinct elements of sequence that do not appear in itemsToExclude.
+ /// Thrown when itemsToExclude is null.
+ let inline except (itemsToExclude: #seq<'T>) (source: NonEmptySeq<'T>) = Seq.except itemsToExclude source |> unsafeOfSeq
+
+ /// Tests if any element of the sequence satisfies the given predicate.
+ /// The function to test the input elements.
+ /// The input sequence.
+ /// True if any element satisfies the predicate.
+ let inline exists (predicate: 'T -> bool) (source: NonEmptySeq<'T>) = Seq.exists predicate source
+
+ /// Tests if any pair of corresponding elements of the sequences satisfies the given predicate.
+ /// The function to test the input elements.
+ /// The first input sequence.
+ /// The second input sequence.
+ /// True if any pair of elements satisfy the predicate.
+ /// Thrown when the input sequences are of different lengths.
+ let inline exists2 (predicate: 'T1 -> 'T2 -> bool) (source1: NonEmptySeq<'T1>) (source2: NonEmptySeq<'T2>) =
+ Seq.exists2 predicate source1 source2
+
+ /// Returns a new collection containing only the elements of the collection for which the given predicate returns "true."
+ /// The function to test the input elements.
+ /// The input sequence.
+ /// A sequence containing only the elements that satisfy the predicate.
+ let inline filter (predicate: 'T -> bool) (source: NonEmptySeq<'T>): NonEmptySeq<'T> =
+ source |> Seq.filter predicate |> unsafeOfSeq
+
+ /// Returns a new collection containing only the elements of the collection for which the given predicate returns "true."
+ /// The function to test the input elements.
+ /// The input sequence.
+ /// A sequence containing only the elements that satisfy the predicate.
+ let inline tryFilter (predicate: 'T -> bool) (source: NonEmptySeq<'T>): 'T seq =
+ source |> Seq.filter predicate
+
+ /// Returns the first element for which the given function returns True.
+ /// Raises if no such element exists.
+ /// The function to test the input elements.
+ /// The input sequence.
+ /// The first element that satisfies the predicate.
+ /// Thrown if the predicate evaluates to false for all the elements of the sequence.
+ let inline find (predicate: 'T -> bool) (source: NonEmptySeq<'T>) = Seq.find predicate source
+
+ /// Returns the last element for which the given function returns True.
+ /// Raises if no such element exists.
+ /// The function to test the input elements.
+ /// The input sequence.
+ /// The first element that satisfies the predicate.
+ /// Thrown if the predicate evaluates to false for all the elements of the sequence.
+ let inline findBack (predicate: 'T -> bool) (source: NonEmptySeq<'T>) = Seq.findBack predicate source
+
+ /// Returns the index of the first element in the sequence that satisfies the given predicate.
+ /// Raises if no such element exists.
+ /// The function to test the input elements.
+ /// The input sequence.
+ /// The first element that satisfies the predicate.
+ /// Thrown if the predicate evaluates to false for all the elements of the sequence.
+ let inline findIndex (predicate: 'T -> bool) (source: NonEmptySeq<'T>) = Seq.findIndex predicate source
+
+ /// Returns the index of the last element in the sequence that satisfies the given predicate.
+ /// Raises if no such element exists.
+ /// The function to test the input elements.
+ /// The input sequence.
+ /// The first element that satisfies the predicate.
+ /// Thrown if the predicate evaluates to false for all the elements of the sequence.
+ let inline findIndexBack (predicate: 'T -> bool) (source: NonEmptySeq<'T>) = Seq.findIndexBack predicate source
+
+ /// Applies a function to each element of the collection, threading an accumulator argument through the computation.
+ /// Take the second argument, and apply the function to it and the first element of the sequence.
+ /// Then feed this result into the function along with the second element and so on.
+ /// Return the final result.
+ /// If the input function is f and the elements are i0...iN then computes f (... (f s i0) i1 ...) iN.
+ /// The function to update the state given the input elements.
+ /// The initial state.
+ /// The input sequence.
+ /// The final state value.
+ let inline fold (folder: 'State -> 'T -> 'State) (state: 'State) (source: NonEmptySeq<'T>) = Seq.fold folder state source
+
+ /// Applies a function to corresponding elements of two collections, threading an accumulator argument through the computation.
+ /// The collections must have identical sizes.
+ /// If the input function is f and the elements are i0...iN and j0...jN then computes f (... (f s i0 j0)...) iN jN.
+ /// The function to update the state given the input elements.
+ /// The initial state.
+ /// The first input sequence.
+ /// The second input sequence.
+ /// The final state value.
+ let inline fold2 (folder: 'State -> 'T1 -> 'T2 -> 'State) (state: 'State) (source1: NonEmptySeq<'T1>) (source2: NonEmptySeq<'T2>) =
+ Seq.fold2 folder state source1 source2
+
+ /// Applies a function to each element of the collection, starting from the end, threading an accumulator argument through the computation.
+ /// Take the second argument, and apply the function to it and the first element of the sequence.
+ /// Then feed this result into the function along with the second element and so on.
+ /// Return the final result.
+ /// If the input function is f and the elements are i0...iN then computes f i0 (...(f iN s)).
+ /// The function to update the state given the input elements.
+ /// The input sequence.
+ /// The initial state.
+ /// The final state value.
+ let inline foldBack (folder: 'T -> 'State -> 'State) (source: NonEmptySeq<'T>) (state: 'State) =
+ Seq.foldBack folder source state
+
+ /// Applies a function to corresponding elements of two collections, threading an accumulator argument through the computation.
+ /// The collections must have identical sizes.
+ /// If the input function is f and the elements are i0...iN and j0...jN then computes f (... (f s i0 j0)...) iN jN.
+ /// The function to update the state given the input elements.
+ /// The first input sequence.
+ /// The second input sequence.
+ /// The initial state.
+ /// The final state value.
+ let inline foldBack2 (folder: 'T1 -> 'T2 -> 'State -> 'State) (source1: NonEmptySeq<'T1>) (source2: NonEmptySeq<'T2>) (state: 'State) =
+ Seq.foldBack2 folder source1 source2 state
+
+ /// Tests if all elements of the collection satisfy the given predicate.
+ /// The function to test the input elements.
+ /// The input sequence.
+ /// True if all of the elements satisfy the predicate.
+ let inline forall (predicate: 'T -> bool) (source: NonEmptySeq<'T>) = Seq.forall predicate source
+
+ /// Tests if all corresponding elements of the collection satisfy the given predicate pairwise.
+ /// The function to test the input elements.
+ /// The first input sequence.
+ /// The second input sequence.
+ /// True if all of the pairs of elements satisfy the predicate.
+ /// Thrown when the input sequences differ in length.
+ let inline forall2 (predicate: 'T1 -> 'T2 -> bool) (source1: NonEmptySeq<'T1>) (source2: NonEmptySeq<'T2>) =
+ Seq.forall2 predicate source1 source2
+
+ /// Applies a key-generating function to each element of a sequence and yields a sequence of unique keys.
+ /// Each unique key contains a sequence of all elements that match to this key.
+ /// A function that transforms an element of the sequence into a comparable key.
+ /// The input sequence.
+ /// The result sequence.
+ let inline groupBy (projection: 'T -> 'U) (source: NonEmptySeq<'T>) =
+ Seq.groupBy projection source
+ |> Seq.map (fun (k, v) -> (k, unsafeOfSeq v))
+ |> unsafeOfSeq
+
/// Returns the first element of the sequence.
///
/// The input sequence.
@@ -151,6 +389,14 @@ module NonEmptySeq =
/// The result sequence.
let indexed (source: NonEmptySeq<_>) = Seq.indexed source |> unsafeOfSeq
+ /// Creates a sequence by applying a function to each index.
+ /// The number of elements to initialize.
+ /// A function that produces an element from an index.
+ /// The result sequence.
+ /// Thrown when count is less than or equal to zero.
+ let init (count: int) (initializer: int -> 'T) : NonEmptySeq<'T> =
+ Seq.init count initializer |> unsafeOfSeq
+
/// Generates a new sequence which, when iterated, will return successive
/// elements by calling the given function. The results of calling the function
/// will not be saved, that is the function will be reapplied as necessary to
@@ -166,6 +412,68 @@ module NonEmptySeq =
/// The result sequence.
let initInfinite initializer = Seq.initInfinite initializer |> unsafeOfSeq
+ /// Inserts an element at the specified index.
+ /// The index at which to insert the element.
+ /// The value to insert.
+ /// The input sequence.
+ /// The result sequence.
+ let insertAt (index: int) (value: 'T) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
+ Seq.insertAt index value source |> unsafeOfSeq
+
+ /// Inserts multiple elements at the specified index.
+ /// The index at which to insert the elements.
+ /// The values to insert.
+ /// The input sequence.
+ /// The result sequence.
+ let insertManyAt (index: int) (values: seq<'T>) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
+ Seq.insertManyAt index values source |> unsafeOfSeq
+
+ /// Returns the element at the specified index.
+ /// The index of the element to retrieve.
+ /// The input sequence.
+ /// The element at the specified index.
+ /// Thrown when index is out of range.
+ let item (index: int) (source: NonEmptySeq<'T>) : 'T =
+ Seq.item index source
+
+ /// Applies a function to each element of the sequence.
+ /// The function to apply to each element.
+ /// The input sequence.
+ let iter (action: 'T -> unit) (source: NonEmptySeq<'T>) : unit =
+ Seq.iter action source
+
+ /// Applies a function to each element of the two sequences.
+ /// The function to apply to each pair of elements.
+ /// The first input sequence.
+ /// The second input sequence.
+ let iter2 (action: 'T1 -> 'T2 -> unit) (source1: NonEmptySeq<'T1>) (source2: NonEmptySeq<'T2>) : unit =
+ Seq.iter2 action source1 source2
+
+ /// Applies a function to each element of the sequence, passing the index of the element as the first argument to the function.
+ /// The function to apply to each element and its index.
+ /// The input sequence.
+ let iteri (action: int -> 'T -> unit) (source: NonEmptySeq<'T>) : unit =
+ Seq.iteri action source
+
+ /// Applies a function to each element of the two sequences, passing the index of the elements as the first argument to the function.
+ /// The function to apply to each pair of elements and their index.
+ /// The first input sequence.
+ /// The second input sequence.
+ let iteri2 (action: int -> 'T1 -> 'T2 -> unit) (source1: NonEmptySeq<'T1>) (source2: NonEmptySeq<'T2>) : unit =
+ Seq.iteri2 action source1 source2
+
+ /// Returns the last element of the sequence.
+ /// The input sequence.
+ /// The last element of the sequence.
+ let last (source: NonEmptySeq<'T>) : 'T =
+ Seq.last source
+
+ /// Returns the last element of the sequence.
+ /// The input sequence.
+ /// The last element of the sequence.
+ let length (source: NonEmptySeq<'T>) : int =
+ Seq.length source
+
/// Builds a new collection whose elements are the results of applying the given function
/// to each of the elements of the collection. The given function will be applied
/// as elements are demanded using the MoveNext method on enumerators retrieved from the
@@ -322,6 +630,14 @@ module NonEmptySeq =
/// This function consumes the whole input sequence before yielding the first element of the result sequence.
let permute indexMap (source: NonEmptySeq<_>) = Seq.permute indexMap source |> unsafeOfSeq
+ /// Returns the first element for which the given function returns Some. If no such element exists, raises KeyNotFoundException.
+ /// A function to transform elements of the sequence into options.
+ /// The input sequence.
+ /// The first chosen element.
+ /// Thrown when no element is chosen.
+ let pick (chooser: 'T -> 'U option) (source: NonEmptySeq<'T>) : 'U =
+ Seq.pick chooser source
+
/// Builds a new sequence object that delegates to the given sequence object. This ensures
/// the original sequence cannot be rediscovered and mutated by a type cast. For example,
/// if given an array the returned sequence will return the elements of the array, but
@@ -332,6 +648,47 @@ module NonEmptySeq =
/// The result sequence.
let readonly (source: NonEmptySeq<_>) = Seq.readonly source |> unsafeOfSeq
+ /// Applies a function to each element of the sequence, threading an accumulator argument
+ /// through the computation. Apply the function to the first two elements of the sequence.
+ /// Then feed this result into the function along with the third element and so on.
+ /// Return the final result. If the input function is f and the elements are i0...iN then computes
+ /// f (... (f i0 i1) i2 ...) iN.
+ /// The function to reduce two sequence elements to a single element.
+ /// The input sequence.
+ /// The final reduced value.
+ let reduce (reduction: 'T -> 'T -> 'T) source = Seq.reduce reduction source
+
+ /// Applies a function to each element of the sequence, starting from the end, threading an accumulator argument
+ /// through the computation. If the input function is f and the elements are i0...iN then computes
+ /// f i0 (...(f iN-1 iN)).
+ /// A function that takes in the next-to-last element of the sequence and the
+ /// current accumulated result to produce the next accumulated result.
+ /// The input sequence.
+ /// The final result of the reductions.
+ let reduceBack (reduction: 'T -> 'T -> 'T) (source: NonEmptySeq<'T>) = Seq.reduceBack reduction source
+
+ /// Removes the element at the specified index.
+ /// The index of the element to remove.
+ /// The input sequence.
+ /// The result sequence.
+ let removeAt (index: int) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
+ Seq.removeAt index source |> unsafeOfSeq
+
+ /// Removes multiple elements starting at the specified index.
+ /// The index at which to start removing elements.
+ /// The number of elements to remove.
+ /// The input sequence.
+ /// The result sequence.
+ let removeManyAt (index: int) (count: int) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
+ Seq.removeManyAt index count source |> unsafeOfSeq
+
+ /// Creates a sequence that contains one repeated value.
+ /// The number of elements.
+ /// The value to replicate.
+ /// The result sequence.
+ let replicate (count: int) (value: 'T) : NonEmptySeq<'T> =
+ Seq.replicate count value |> unsafeOfSeq
+
/// Returns a new sequence with the elements in reverse order.
/// The input sequence.
/// The reversed sequence.
@@ -367,6 +724,20 @@ module NonEmptySeq =
/// The result sequence of one item.
let singleton value = Seq.singleton value |> unsafeOfSeq
+ /// Returns a sequence that skips the first N elements of the list.
+ /// The number of elements to skip.
+ /// The input sequence.
+ /// The result sequence.
+ let skip (count: int) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
+ Seq.skip count source |> unsafeOfSeq
+
+ /// Returns a sequence that skips elements while the predicate is true.
+ /// A function to test each element of the sequence.
+ /// The input sequence.
+ /// The result sequence.
+ let skipWhile (predicate: 'T -> bool) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
+ Seq.skipWhile predicate source |> unsafeOfSeq
+
/// Yields a sequence ordered by keys.
///
/// This function returns a sequence that digests the whole initial sequence as soon as
@@ -443,6 +814,26 @@ module NonEmptySeq =
///
/// The result sequence.
let sortByDescending projection (source: NonEmptySeq<_>) = Seq.sortByDescending projection source |> unsafeOfSeq
+
+ /// Splits the list into the specified number of sequences.
+ /// The number of sequences to create.
+ /// The input list.
+ /// A sequence of sequences.
+ let splitInto (count: int) (source: NonEmptySeq<'T>) : NonEmptySeq> =
+ Seq.splitInto count source |> Seq.map unsafeOfSeq |> unsafeOfSeq
+
+ /// Computes the sum of the elements of the sequence.
+ /// The input sequence.
+ /// The sum of the elements.
+ let inline sum source =
+ Seq.sum source
+
+ /// Computes the sum of the elements of the sequence, using the given projection.
+ /// A function to transform the sequence elements before summing.
+ /// The input sequence.
+ /// The sum of the transformed elements.
+ let inline sumBy projection source =
+ Seq.sumBy projection source
/// Returns a sequence that skips 1 element of the underlying sequence and then yields the
/// remaining elements of the sequence.
@@ -452,6 +843,86 @@ module NonEmptySeq =
/// The result sequence.
let tail (source: NonEmptySeq<_>) = Seq.tail source
+ /// Returns a sequence that contains the first N elements of the sequence.
+ /// The number of elements to take.
+ /// The input sequence.
+ /// The result sequence.
+ let take (count: int) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
+ Seq.take count source |> unsafeOfSeq
+
+ /// Returns a sequence that contains the elements of the sequence while the predicate is true.
+ /// A function to test each element of the sequence.
+ /// The input sequence.
+ /// The result sequence.
+ let takeWhile (predicate: 'T -> bool) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
+ Seq.takeWhile predicate source |> unsafeOfSeq
+
+ /// Truncates the sequence to the specified length.
+ /// The maximum number of elements to include in the sequence.
+ /// The input sequence.
+ /// The truncated sequence.
+ let truncate (count: int) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
+ Seq.truncate count source |> unsafeOfSeq
+
+ /// Returns the only element of the sequence, or None if the sequence does not contain exactly one element.
+ /// The input sequence.
+ /// The only element of the sequence, or None.
+ let tryExactlyOne (source: NonEmptySeq<'T>) : 'T option =
+ Seq.tryExactlyOne source
+
+ /// Returns the first element for which the given function returns true, or None if no such element exists.
+ /// A function to test each element of the sequence.
+ /// The input sequence.
+ /// The first element for which the predicate returns true, or None.
+ let tryFind (predicate: 'T -> bool) (source: NonEmptySeq<'T>) : 'T option =
+ Seq.tryFind predicate source
+
+ /// Returns the last element for which the given function returns true, or None if no such element exists.
+ /// A function to test each element of the sequence.
+ /// The input sequence.
+ /// The last element for which the predicate returns true, or None.
+ let tryFindBack (predicate: 'T -> bool) (source: NonEmptySeq<'T>) : 'T option =
+ Seq.tryFindBack predicate source
+
+ /// Returns the index of the first element for which the given function returns true, or None if no such element exists.
+ /// A function to test each element of the sequence.
+ /// The input sequence.
+ /// The index of the first element for which the predicate returns true, or None.
+ let tryFindIndex (predicate: 'T -> bool) (source: NonEmptySeq<'T>) : int option =
+ Seq.tryFindIndex predicate source
+
+ /// Returns the index of the last element for which the given function returns true, or None if no such element exists.
+ /// A function to test each element of the sequence.
+ /// The input sequence.
+ /// The index of the last element for which the predicate returns true, or None.
+ let tryFindIndexBack (predicate: 'T -> bool) (source: NonEmptySeq<'T>) : int option =
+ Seq.tryFindIndexBack predicate source
+
+ /// Returns the element at the specified index, or None if the index is out of range.
+ /// The index of the element to retrieve.
+ /// The input sequence.
+ /// The element at the specified index, or None.
+ let tryItem (index: int) (source: NonEmptySeq<'T>) : 'T option =
+ Seq.tryItem index source
+
+ /// Returns the last element of the sequence, or None if the sequence is empty.
+ /// The input sequence.
+ /// The last element of the sequence, or None.
+ let tryLast (source: NonEmptySeq<'T>) : 'T option =
+ Seq.tryLast source
+
+ /// Returns the first element for which the given function returns Some, or None if no such element exists.
+ /// A function to transform elements of the sequence into options.
+ /// The input sequence.
+ /// The first chosen element, or None.
+ let tryPick (chooser: 'T -> 'U option) (source: NonEmptySeq<'T>) : 'U option =
+ Seq.tryPick chooser source
+
+ /// Generates a list by repeatedly applying a function to a state.
+ /// A function that takes the current state and returns an option tuple of the next element and the next state.
+ /// The initial element.
+ /// The initial state.
+ /// The result list.
let unfold (generator: 'T -> 'State -> ('T * 'State) option) (head: 'T) (state: 'State) =
let rec go item state =
seq {
@@ -462,6 +933,34 @@ module NonEmptySeq =
}
go head state |> unsafeOfSeq
+ /// Splits a sequence of triples into three sequences.
+ /// The input sequence.
+ /// A tuple containing the three sequences.
+ let unzip3 (source: NonEmptySeq<'T1 * 'T2 * 'T3>) : NonEmptySeq<'T1> * NonEmptySeq<'T2> * NonEmptySeq<'T3> =
+ source |> Seq.toList |> List.unzip3 |> fun (a, b, c) -> (unsafeOfSeq a, unsafeOfSeq b, unsafeOfSeq c)
+
+ /// Updates the element at the specified index.
+ /// The index of the element to update.
+ /// The new value.
+ /// The input sequence.
+ /// The result sequence.
+ let updateAt (index: int) (value: 'T) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
+ Seq.updateAt index value source |> unsafeOfSeq
+
+ /// Returns a sequence that contains the elements of the sequence for which the given function returns true.
+ /// A function to test each element of the sequence.
+ /// The input sequence.
+ /// The result sequence.
+ let where (predicate: 'T -> bool) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
+ Seq.where predicate source |> unsafeOfSeq
+
+ /// Returns a sequence of sliding windows containing elements drawn from the sequence.
+ /// The number of elements in each window.
+ /// The input sequence.
+ /// The sequence of windows.
+ let windowed (windowSize: int) (source: NonEmptySeq<'T>) : NonEmptySeq> =
+ Seq.windowed windowSize source |> Seq.map unsafeOfSeq |> unsafeOfSeq
+
/// Combines the two sequences into a sequence of pairs. The two sequences need not have equal lengths:
/// when one sequence is exhausted any remaining elements in the other
/// sequence are ignored.
@@ -518,23 +1017,6 @@ module NonEmptySeq =
let replace (oldValue: NonEmptySeq<'T>) (newValue: NonEmptySeq<'T>) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
Seq.replace oldValue newValue source |> unsafeOfSeq
- /// Returns a sequence that contains no duplicate entries according to the generic hash and equality comparisons
- /// on the keys returned by the given key-generating function.
- /// If an element occurs multiple times in the sequence then the later occurrences are discarded.
- /// The input sequence.
- /// The resulting sequence without duplicates.
- let distinct (source: NonEmptySeq<'T>) = source |> Seq.distinct |> ofSeq
-
- /// Applies a function to each element of the sequence, threading an accumulator argument
- /// through the computation. Apply the function to the first two elements of the sequence.
- /// Then feed this result into the function along with the third element and so on.
- /// Return the final result. If the input function is f and the elements are i0...iN then computes
- /// f (... (f i0 i1) i2 ...) iN.
- /// The function to reduce two sequence elements to a single element.
- /// The input sequence.
- /// The final reduced value.
- let reduce (reduction: 'T -> 'T -> 'T) source = Seq.reduce reduction source
-
[]
module NonEmptySeqBuilder =