From e10b8d0400a54ea1d444c1b23762d9cac0f14f00 Mon Sep 17 00:00:00 2001 From: Patrick McDonald Date: Mon, 18 May 2015 15:34:02 -0700 Subject: [PATCH] truncate should not throw ArgumentException when count is negative fixes #453 closes #454 --- .../FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs | 3 ++- .../FSharp.Core/Microsoft.FSharp.Collections/ListModule2.fs | 3 ++- .../FSharp.Core/Microsoft.FSharp.Collections/SeqModule2.fs | 5 +++++ src/fsharp/FSharp.Core/array.fs | 3 +-- src/fsharp/FSharp.Core/array.fsi | 1 - src/fsharp/FSharp.Core/list.fsi | 1 - src/fsharp/FSharp.Core/local.fs | 5 ++--- 7 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs index 719a274f2e..888f9eb709 100644 --- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs +++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs @@ -939,7 +939,8 @@ type ArrayModule2() = CheckThrowsArgumentNullException(fun() -> Array.truncate 1 null |> ignore) // negative count - CheckThrowsArgumentException(fun() -> Array.truncate -1 [|1..5|] |> ignore) + Assert.AreEqual([| |], Array.truncate -1 [|1..5|]) + Assert.AreEqual([| |], Array.truncate System.Int32.MinValue [|1..5|]) () diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ListModule2.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ListModule2.fs index eb3db7ca81..827ffba4b9 100644 --- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ListModule2.fs +++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ListModule2.fs @@ -815,7 +815,8 @@ type ListModule02() = Assert.AreEqual([], List.truncate 1 []) // negative count - CheckThrowsArgumentException(fun() -> List.truncate -1 [1..5] |> ignore) + Assert.AreEqual([], List.truncate -1 [1..5]) + Assert.AreEqual([], List.truncate System.Int32.MinValue [1..5]) () diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule2.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule2.fs index 1693f926be..31de923bcc 100644 --- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule2.fs +++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule2.fs @@ -1533,6 +1533,11 @@ type SeqModule2() = // null Seq CheckThrowsArgumentNullException(fun() -> Seq.truncate 1 null |> ignore) + + // negative count + VerifySeqsEqual Seq.empty <| Seq.truncate -1 (seq [1;2;4;5;7]) + VerifySeqsEqual Seq.empty <| Seq.truncate System.Int32.MinValue (seq [1;2;4;5;7]) + () [] diff --git a/src/fsharp/FSharp.Core/array.fs b/src/fsharp/FSharp.Core/array.fs index 57e023123a..8501a3f19b 100644 --- a/src/fsharp/FSharp.Core/array.fs +++ b/src/fsharp/FSharp.Core/array.fs @@ -1001,8 +1001,7 @@ namespace Microsoft.FSharp.Collections [] let truncate count (array:'T[]) = checkNonNull "array" array - if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative)) - if count = 0 then empty + if count <= 0 then empty else let len = array.Length let count' = Operators.min count len diff --git a/src/fsharp/FSharp.Core/array.fsi b/src/fsharp/FSharp.Core/array.fsi index a683eaeeba..95b8287436 100644 --- a/src/fsharp/FSharp.Core/array.fsi +++ b/src/fsharp/FSharp.Core/array.fsi @@ -981,7 +981,6 @@ namespace Microsoft.FSharp.Collections /// The input array. /// The result array. /// Thrown when the input array is null. - /// Thrown when the count is negative. [] val truncate: count:int -> array:'T[] -> 'T[] diff --git a/src/fsharp/FSharp.Core/list.fsi b/src/fsharp/FSharp.Core/list.fsi index fe1a149750..dfffdce32e 100644 --- a/src/fsharp/FSharp.Core/list.fsi +++ b/src/fsharp/FSharp.Core/list.fsi @@ -778,7 +778,6 @@ namespace Microsoft.FSharp.Collections /// The maximum number of items to return. /// The input list. /// The result list. - /// Thrown when the count is negative. [] val truncate: count:int -> list:'T list -> 'T list diff --git a/src/fsharp/FSharp.Core/local.fs b/src/fsharp/FSharp.Core/local.fs index 0b3b0a434b..ae109683b7 100644 --- a/src/fsharp/FSharp.Core/local.fs +++ b/src/fsharp/FSharp.Core/local.fs @@ -441,17 +441,16 @@ module internal List = truncateToFreshConsTail cons2 (count-1) t let truncate count list = - if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative)) match list with | [] -> list | _ :: ([] as nil) -> if count > 0 then list else nil | h::t -> - if count = 0 then [] + if count <= 0 then [] else let cons = freshConsNoTail h truncateToFreshConsTail cons (count-1) t cons - + let rec unfoldToFreshConsTail cons f s = match f s with | None -> setFreshConsTail cons []