diff --git a/src/FSharpPlus/Data/NonEmptyList.fs b/src/FSharpPlus/Data/NonEmptyList.fs
index b5bdc4611..f4e4487b9 100644
--- a/src/FSharpPlus/Data/NonEmptyList.fs
+++ b/src/FSharpPlus/Data/NonEmptyList.fs
@@ -199,7 +199,6 @@ module NonEmptyList =
/// The first input list.
/// The second input list.
/// The resulting list of pairs.
-
let inline allPairs (list1: NonEmptyList<'T>) (list2: NonEmptyList<'U>) = Seq.allPairs list1 list2 |> ofSeq
/// Concatenates two lists.
@@ -218,7 +217,8 @@ module NonEmptyList =
/// 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: NonEmptyList<'T>) = List.averageBy projection (list.Head :: list.Tail)
+ let inline averageBy (projection: 'T -> ^U) (list: NonEmptyList<'T>) =
+ Seq.averageBy projection list
///
/// Applies a function to each element in a list and then returns a list of values v where the applied function returned Some(v).
@@ -226,7 +226,8 @@ module NonEmptyList =
/// The function to be applied to the list elements.
/// The input list.
/// The resulting list comprising the values v where the chooser function returned Some(x).
- let inline choose chooser (list: NonEmptyList<'T>) = list |> Seq.choose chooser |> ofSeq
+ let inline tryChoose chooser (list: NonEmptyList<'T>) =
+ list |> Seq.choose chooser |> List.ofSeq
///
/// Applies a function to each element in a list and then returns a list of values v where the applied function returned Some(v).
@@ -234,29 +235,32 @@ module NonEmptyList =
/// The function to be applied to the list elements.
/// The input list.
/// The resulting list comprising the values v where the chooser function returned Some(x).
- let inline tryChoose chooser (list: NonEmptyList<'T>) = list |> Seq.choose chooser |> List.ofSeq
+ /// Thrown when the chooser function returns None for all elements.
+ let inline choose chooser (list: NonEmptyList<'T>) =
+ tryChoose chooser list |> ofList
/// 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 list.
/// The list divided into chunks.
- let inline chunkBySize chunkSize (list: NonEmptyList<'T>) =
- list.Head :: list.Tail |> List.chunkBySize chunkSize |> List.map ofList
+ let inline chunkBySize chunkSize (list: NonEmptyList<'T>): NonEmptyList> =
+ list.Head :: list.Tail |> List.chunkBySize chunkSize |> List.map ofList |> ofList
/// 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 list.
/// The concatenation of the transformed sublists.
- let inline collect mapping (list: NonEmptyList<'T>) = list |> Seq.collect mapping |> ofSeq
+ let inline tryCollect mapping (list: NonEmptyList<'T>) = list |> Seq.collect mapping |> List.ofSeq
/// 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 list.
/// The concatenation of the transformed sublists.
- let inline tryCollect mapping (list: NonEmptyList<'T>) = list |> Seq.collect mapping |> List.ofSeq
+ /// Thrown when the mapping function returns an empty list for all element.
+ let inline collect mapping (list: NonEmptyList<'T>) = list >>= mapping
/// Returns a new list that contains the elements of each of the lists in order.
/// The input list of lists.
@@ -340,15 +344,16 @@ module NonEmptyList =
/// The function to test the input elements.
/// The input list.
/// A list containing only the elements that satisfy the predicate.
- let inline filter (predicate: 'T -> bool) (list: NonEmptyList<'T>): NonEmptyList<'T> =
- list |> toList |> List.filter predicate |> ofList
+ let inline tryFilter (predicate: 'T -> bool) (list: NonEmptyList<'T>): 'T list =
+ list |> Seq.filter predicate |> List.ofSeq
/// 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 list.
/// A list containing only the elements that satisfy the predicate.
- let inline tryFilter (predicate: 'T -> bool) (list: NonEmptyList<'T>): 'T list =
- list |> toList |> List.filter predicate
+ /// Thrown when the predicate evaluates to false for all the elements of the list.
+ let inline filter (predicate: 'T -> bool) (list: NonEmptyList<'T>): NonEmptyList<'T> =
+ list |> tryFilter predicate |> ofList
/// Returns the first element for which the given function returns True.
/// Raises if no such element exists.
@@ -596,8 +601,8 @@ module NonEmptyList =
/// A function to test each element of the list.
/// The input list.
/// A tuple containing the two lists.
- let partition (predicate: 'T -> bool) (list: NonEmptyList<'T>) : NonEmptyList<'T> * NonEmptyList<'T> =
- list |> toList |> List.partition predicate |> fun (a, b) -> (ofList a, ofList b)
+ let partition (predicate: 'T -> bool) (list: NonEmptyList<'T>) : 'T list * 'T list =
+ list |> toList |> List.partition predicate |> fun (a, b) -> (a, b)
/// Applies a function to each element of the list, returning a list of the results in a random order.
/// A function to generate a permutation of the list indices.
@@ -639,17 +644,34 @@ module NonEmptyList =
/// Removes the element at the specified index.
/// The index of the element to remove.
/// The input list.
- /// The result list.
+ /// The resulting list.
+ let tryRemoveAt (index: int) (list: NonEmptyList<'T>) : 'T list =
+ list |> Seq.removeAt index |> List.ofSeq
+
+ /// Removes the element at the specified index.
+ /// The index of the element to remove.
+ /// The input list.
+ /// The resulting list.
+ /// Thrown when removing the item results in an empty list.
let removeAt (index: int) (list: NonEmptyList<'T>) : NonEmptyList<'T> =
- Seq.removeAt index list |> ofSeq
+ tryRemoveAt index list |> ofList
/// Removes multiple elements starting at the specified index.
/// The index at which to start removing elements.
/// The number of elements to remove.
/// The input list.
/// The result list.
+ let tryRemoveManyAt (index: int) (count: int) (list: NonEmptyList<'T>) : 'T list =
+ list |> Seq.removeManyAt index count |> List.ofSeq
+
+ /// Removes multiple elements starting at the specified index.
+ /// The index at which to start removing elements.
+ /// The number of elements to remove.
+ /// The input list.
+ /// The result list.
+ /// Thrown when removing the items results in an empty list.
let removeManyAt (index: int) (count: int) (list: NonEmptyList<'T>) : NonEmptyList<'T> =
- Seq.removeManyAt index count list |> ofSeq
+ tryRemoveManyAt index count list |> ofList
/// Creates a list that contains one repeated value.
/// The number of elements.
@@ -684,15 +706,31 @@ module NonEmptyList =
/// The number of elements to skip.
/// The input list.
/// The result list.
+ let trySkip (count: int) (list: NonEmptyList<'T>) : 'T list =
+ list |> Seq.skip count |> List.ofSeq
+
+ /// Returns a list that skips the first N elements of the list.
+ /// The number of elements to skip.
+ /// The input list.
+ /// The result list.
+ /// Thrown when resulting list is empty.
let skip (count: int) (list: NonEmptyList<'T>) : NonEmptyList<'T> =
- Seq.skip count list |> ofSeq
+ trySkip count list |> ofList
/// Returns a list that skips elements while the predicate is true.
/// A function to test each element of the list.
/// The input list.
/// The result list.
+ let trySkipWhile (predicate: 'T -> bool) (list: NonEmptyList<'T>) : 'T list =
+ list |> Seq.skipWhile predicate |> List.ofSeq
+
+ /// Returns a list that skips elements while the predicate is true.
+ /// A function to test each element of the list.
+ /// The input list.
+ /// The result list.
+ /// Thrown when resulting list is empty.
let skipWhile (predicate: 'T -> bool) (list: NonEmptyList<'T>) : NonEmptyList<'T> =
- Seq.skipWhile predicate list |> ofSeq
+ trySkipWhile predicate list |> ofList
/// Sorts the elements of the list in ascending order.
/// The input list.
@@ -731,8 +769,14 @@ module NonEmptyList =
/// The index at which to split the list.
/// The input list.
/// A tuple containing the two lists.
+ /// Thrown when the index is 0, equal to the size of the list, or is larger than the list.
let splitAt (index: int) (list: NonEmptyList<'T>) : NonEmptyList<'T> * NonEmptyList<'T> =
- list |> toList |> List.splitAt index |> fun (a, b) -> (ofList a, ofList b)
+ if index <= 0 then
+ raise <| new System.InvalidOperationException("Index must be greater than 0.")
+ else if index >= list.Length then
+ raise <| new System.InvalidOperationException("Index must be less than the length of the list.")
+ else
+ list |> toList |> List.splitAt index |> fun (a, b) -> (ofList a, ofList b)
/// Splits the list into the specified number of lists.
/// The number of lists to create.
@@ -758,22 +802,51 @@ module NonEmptyList =
/// The number of elements to take.
/// The input list.
/// The result list.
+ let tryTake (count: int) (list: NonEmptyList<'T>) : 'T list =
+ Seq.take count list |> List.ofSeq
+
+ /// Returns a list that contains the first N elements of the list.
+ /// The number of elements to take.
+ /// The input list.
+ /// The result list.
+ /// Thrown when the count is less than or equal to zero.
let take (count: int) (list: NonEmptyList<'T>) : NonEmptyList<'T> =
- Seq.take count list |> ofSeq
+ if count <= 0 then
+ raise <| new System.ArgumentException("Count must be greater than 0.")
+ else
+ tryTake count list |> ofList
+
+ /// Returns a list that contains the elements of the list while the predicate is true.
+ /// A function to test each element of the list.
+ /// The input list.
+ /// The result list.
+ let tryTakeWhile (predicate: 'T -> bool) (list: NonEmptyList<'T>) : 'T list =
+ Seq.takeWhile predicate list |> List.ofSeq
/// Returns a list that contains the elements of the list while the predicate is true.
/// A function to test each element of the list.
/// The input list.
/// The result list.
+ /// Thrown when resulting list is empty.
let takeWhile (predicate: 'T -> bool) (list: NonEmptyList<'T>) : NonEmptyList<'T> =
- Seq.takeWhile predicate list |> ofSeq
+ tryTakeWhile predicate list |> ofList
+
+ /// Truncates the list to the specified length.
+ /// The maximum number of elements to include in the list.
+ /// The input list.
+ /// The truncated list.
+ let tryTruncate (count: int) (list: NonEmptyList<'T>) : 'T list =
+ Seq.truncate count list |> List.ofSeq
/// Truncates the list to the specified length.
/// The maximum number of elements to include in the list.
/// The input list.
/// The truncated list.
let truncate (count: int) (list: NonEmptyList<'T>) : NonEmptyList<'T> =
- Seq.truncate count list |> ofSeq
+ if count <= 0 then
+ raise <| new System.ArgumentException("Count must be greater than 0.")
+ else
+ tryTruncate count list |> ofList
/// Returns the only element of the list, or None if the list does not contain exactly one element.
/// The input list.
diff --git a/src/FSharpPlus/Data/NonEmptySeq.fs b/src/FSharpPlus/Data/NonEmptySeq.fs
index 967445937..45c321b46 100644
--- a/src/FSharpPlus/Data/NonEmptySeq.fs
+++ b/src/FSharpPlus/Data/NonEmptySeq.fs
@@ -121,30 +121,31 @@ module NonEmptySeq =
/// 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).
+ /// Applies a function to each element in a sequence and then returns a sequence 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
-
+ /// The resulting sequence comprising the values v where the chooser function returned Some(x).
+ let inline tryChoose chooser (source: NonEmptySeq<'T>) = source |> Seq.choose chooser
+
///
- /// Applies a function to each element in a list and then returns a list of values v where the applied function returned Some(v).
+ /// Applies a function to each element in a sequence and then returns a sequence of values v where the applied function returned Some(v).
///
- /// The function to be applied to the list elements.
+ /// The function to be applied to the sequence 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
+ /// The resulting sequence comprising the values v where the chooser function returned Some(x).
+ /// Thrown when the chooser function returns None for all elements.
+ let inline choose chooser (source: NonEmptySeq<'T>) = source |> tryChoose chooser |> unsafeOfSeq
- /// Divides the input list into lists (chunks) of size at most chunkSize.
- /// Returns a new list containing the generated lists (chunks) as its elements.
+ /// Divides the input sequence into sequences (chunks) of size at most chunkSize.
+ /// Returns a new sequence containing the generated sequences (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
+ let inline chunkBySize chunkSize (source: NonEmptySeq<'T>): NonEmptySeq> =
+ source |> Seq.chunkBySize chunkSize |> Seq.map unsafeOfSeq |> unsafeOfSeq
/// Applies the given function to each element of the sequence and concatenates all the
/// results.
@@ -671,16 +672,33 @@ module NonEmptySeq =
/// The index of the element to remove.
/// The input sequence.
/// The result sequence.
+ let tryRemoveAt (index: int) (source: NonEmptySeq<'T>) : 'T seq =
+ Seq.removeAt index source
+
+ /// Removes the element at the specified index.
+ /// The index of the element to remove.
+ /// The input sequence.
+ /// The result sequence.
+ /// Thrown when removing the item results in an empty sequence.
let removeAt (index: int) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
- Seq.removeAt index source |> unsafeOfSeq
+ tryRemoveAt 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 tryRemoveManyAt (index: int) (count: int) (source: NonEmptySeq<'T>) : 'T seq =
+ Seq.removeManyAt index count source
+
+ /// 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.
+ /// Thrown when removing the items results in an empty sequence.
let removeManyAt (index: int) (count: int) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
- Seq.removeManyAt index count source |> unsafeOfSeq
+ tryRemoveManyAt index count source |> unsafeOfSeq
/// Creates a sequence that contains one repeated value.
/// The number of elements.
@@ -728,15 +746,31 @@ module NonEmptySeq =
/// The number of elements to skip.
/// The input sequence.
/// The result sequence.
+ let trySkip (count: int) (source: NonEmptySeq<'T>) : 'T seq =
+ Seq.skip count source
+
+ /// Returns a sequence that skips the first N elements of the list.
+ /// The number of elements to skip.
+ /// The input sequence.
+ /// The result sequence.
+ /// Thrown when resulting list is empty.
let skip (count: int) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
- Seq.skip count source |> unsafeOfSeq
+ trySkip 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 trySkipWhile (predicate: 'T -> bool) (source: NonEmptySeq<'T>) : 'T seq =
+ Seq.skipWhile predicate source
+
+ /// 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.
+ /// Thrown when resulting list is empty.
let skipWhile (predicate: 'T -> bool) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
- Seq.skipWhile predicate source |> unsafeOfSeq
+ trySkipWhile predicate source |> unsafeOfSeq
/// Yields a sequence ordered by keys.
///
@@ -847,21 +881,44 @@ module NonEmptySeq =
/// The number of elements to take.
/// The input sequence.
/// The result sequence.
+ let tryTake (count: int) (source: NonEmptySeq<'T>) : 'T seq =
+ Seq.take count 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.
+ /// Thrown when the count is less than or equal to zero.
let take (count: int) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
- Seq.take count source |> unsafeOfSeq
+ if count <= 0 then
+ raise <| new System.ArgumentException("Count must be greater than 0.")
+ else
+ tryTake 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 tryTakeWhile (predicate: 'T -> bool) (source: NonEmptySeq<'T>) : 'T seq =
+ Seq.takeWhile predicate source
/// 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.
+ /// Thrown when resulting sequence is empty.
let takeWhile (predicate: 'T -> bool) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
- Seq.takeWhile predicate source |> unsafeOfSeq
+ tryTakeWhile 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.
+ /// Thrown when the count is less than or equal to zero.
let truncate (count: int) (source: NonEmptySeq<'T>) : NonEmptySeq<'T> =
+ if count <= 0 then
+ raise <| new System.ArgumentException("Count must be greater than 0.")
+ else
Seq.truncate count source |> unsafeOfSeq
/// Returns the only element of the sequence, or None if the sequence does not contain exactly one element.