From ec2dd7dec817ce23ff9862282bbfbe3738e503c8 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 28 Feb 2023 12:31:41 +0100 Subject: [PATCH 1/8] Searching functions added --- src/FSharp.Core/array.fs | 42 ++++++++++++++++++ src/FSharp.Core/array.fsi | 93 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) diff --git a/src/FSharp.Core/array.fs b/src/FSharp.Core/array.fs index 8c2fa8470fa..b3c265141a0 100644 --- a/src/FSharp.Core/array.fs +++ b/src/FSharp.Core/array.fs @@ -1934,6 +1934,48 @@ module Array = module Parallel = open System.Threading.Tasks + [] + let tryFindIndex predicate (array: _[]) = + checkNonNull "array" array + + let pResult = + Parallel.For( + 0, + array.Length, + body = + (fun i pState -> + if predicate array[i] then + pState.Break()) + ) + + pResult.LowestBreakIteration |> Option.ofNullable |> Option.map int + + [] + let tryFind predicate (array: _[]) = + array |> tryFindIndex predicate |> Option.map (fun i -> array.[i]) + + [] + let tryPick chooser (array: _[]) = + checkNonNull "array" array + let allChosen = new System.Collections.Concurrent.ConcurrentDictionary<_, _>() + + let pResult = + Parallel.For( + 0, + array.Length, + body = + (fun i pState -> + match chooser array[i] with + | None -> () + | chosenElement -> + allChosen[i] <- chosenElement + pState.Break()) + ) + + pResult.LowestBreakIteration + |> Option.ofNullable + |> Option.bind (fun i -> allChosen[int i]) + [] let choose chooser (array: 'T[]) = checkNonNull "array" array diff --git a/src/FSharp.Core/array.fsi b/src/FSharp.Core/array.fsi index 2d08d1116e1..7bf6b50544c 100644 --- a/src/FSharp.Core/array.fsi +++ b/src/FSharp.Core/array.fsi @@ -3094,6 +3094,99 @@ module Array = /// Provides parallel operations on arrays module Parallel = + /// Returns the first element for which the given function returns True. + /// Return None if no such element exists. + /// + /// The function to test the input elements. + /// The input array. + /// + /// The first element that satisfies the predicate, or None. + /// + /// Thrown when the input array is null. + /// + /// Try to find the first even number: + /// + /// let inputs = [| 1; 2; 3 |] + /// + /// inputs |> Array.Parallel.tryFind (fun elm -> elm % 2 = 0) + /// + /// Evaluates to Some 2 + /// + /// + /// Try to find the first even number: + /// + /// let inputs = [| 1; 5; 3 |] + /// + /// inputs |> Array.Parallel.tryFind (fun elm -> elm % 2 = 0) + /// + /// Evaluates to None + /// + [] + val tryFind: predicate:('T -> bool) -> array:'T[] -> 'T option + + + /// Returns the index of the first element in the array + /// that satisfies the given predicate. + /// + /// The function to test the input elements. + /// The input array. + /// + /// Thrown when the input array is null. + /// + /// The index of the first element that satisfies the predicate, or None. + /// + /// Try to find the index of the first even number: + /// + /// let inputs = [| 1; 2; 3; 4; 5 |] + /// + /// inputs |> Array.Parallel.tryFindIndex (fun elm -> elm % 2 = 0) + /// + /// Evaluates to Some 1 + /// + /// + /// Try to find the index of the first even number: + /// + /// let inputs = [| 1; 3; 5; 7 |] + /// + /// inputs |> Array.Parallel.tryFindIndex (fun elm -> elm % 2 = 0) + /// + /// Evaluates to None + /// + [] + val tryFindIndex : predicate:('T -> bool) -> array:'T[] -> int option + + /// Applies the given function to successive elements, returning the first + /// result where the function returns Some(x) for some x. If the function + /// never returns Some(x) then None is returned. + /// + /// The function to transform the array elements into options. + /// The input array. + /// + /// The first transformed element that is Some(x). + /// + /// Thrown when the input array is null. + /// + /// + /// + /// let input = [| 1; 2; 3 |] + /// + /// input |> Array.Parallel.tryPick (fun n -> if n % 2 = 0 then Some (string n) else None) + /// + /// Evaluates to Some "2". + /// + /// + /// + /// + /// let input = [| 1; 2; 3 |] + /// + /// input |> Array.Parallel.tryPick (fun n -> if n > 3 = 0 then Some (string n) else None) + /// + /// Evaluates to None. + /// + /// + [] + val tryPick: chooser:('T -> 'U option) -> array:'T[] -> 'U option + /// Apply the given function to each element of the array. Return /// the array comprised of the results x for each element where /// the function returns Some(x). From 5f17d1841176edbead8e32acc8c980912d139621 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 28 Feb 2023 14:06:13 +0100 Subject: [PATCH 2/8] Search functions added to surface area --- .../FSharp.Core.SurfaceArea.netstandard20.debug.bsl | 3 +++ .../FSharp.Core.SurfaceArea.netstandard20.release.bsl | 3 +++ .../FSharp.Core.SurfaceArea.netstandard21.debug.bsl | 3 +++ .../FSharp.Core.SurfaceArea.netstandard21.release.bsl | 3 +++ 4 files changed, 12 insertions(+) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl index 348c413de1b..783f3bc30aa 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl @@ -40,6 +40,9 @@ Microsoft.FSharp.Collections.Array4DModule: T[,,,] Create[T](Int32, Int32, Int32 Microsoft.FSharp.Collections.Array4DModule: T[,,,] Initialize[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]]) Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, Int32, Int32) Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T) +Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[]) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl index 2d5ddb40c7a..bca7a6bb25a 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl @@ -40,6 +40,9 @@ Microsoft.FSharp.Collections.Array4DModule: T[,,,] Create[T](Int32, Int32, Int32 Microsoft.FSharp.Collections.Array4DModule: T[,,,] Initialize[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]]) Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, Int32, Int32) Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T) +Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[]) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl index 45805d53ae0..614ec47f2d7 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl @@ -40,6 +40,9 @@ Microsoft.FSharp.Collections.Array4DModule: T[,,,] Create[T](Int32, Int32, Int32 Microsoft.FSharp.Collections.Array4DModule: T[,,,] Initialize[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]]) Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, Int32, Int32) Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T) +Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[]) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl index 275087e02e0..702f3302cee 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl @@ -40,6 +40,9 @@ Microsoft.FSharp.Collections.Array4DModule: T[,,,] Create[T](Int32, Int32, Int32 Microsoft.FSharp.Collections.Array4DModule: T[,,,] Initialize[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]]) Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, Int32, Int32) Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T) +Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[]) From 6c3355d5149c248e46c77bccd0b56408333902bd Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 28 Feb 2023 14:06:49 +0100 Subject: [PATCH 3/8] Formatting --- src/FSharp.Core/array.fs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/FSharp.Core/array.fs b/src/FSharp.Core/array.fs index b3c265141a0..d478d2d23f0 100644 --- a/src/FSharp.Core/array.fs +++ b/src/FSharp.Core/array.fs @@ -1942,10 +1942,9 @@ module Array = Parallel.For( 0, array.Length, - body = - (fun i pState -> - if predicate array[i] then - pState.Break()) + (fun i pState -> + if predicate array[i] then + pState.Break()) ) pResult.LowestBreakIteration |> Option.ofNullable |> Option.map int @@ -1963,13 +1962,12 @@ module Array = Parallel.For( 0, array.Length, - body = - (fun i pState -> - match chooser array[i] with - | None -> () - | chosenElement -> - allChosen[i] <- chosenElement - pState.Break()) + (fun i pState -> + match chooser array[i] with + | None -> () + | chosenElement -> + allChosen[i] <- chosenElement + pState.Break()) ) pResult.LowestBreakIteration From 765a913c1fb0862f1bf13d82ecc0c8a79936e36e Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 9 Mar 2023 14:55:35 +0100 Subject: [PATCH 4/8] Tests for parallel search functions --- .../ArrayModule.fs | 21 ++++++----- .../ArrayModule2.fs | 35 +++++++++++++------ .../CollectionModulesConsistency.fs | 12 +++++-- 3 files changed, 46 insertions(+), 22 deletions(-) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs index 3d9185468d9..2c68635b3b9 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs @@ -955,17 +955,16 @@ type ArrayModule() = let intArr = [| 1..10 |] let seq = Array.toSeq intArr let sum = Seq.sum seq - Assert.AreEqual(55, sum) - - [] - member this.TryPick() = + Assert.AreEqual(55, sum) + + member private _.TryPickTester tryPickInt tryPickString = // integer array let intArr = [| 1..10 |] let funcInt x = match x with | _ when x % 3 = 0 -> Some (x.ToString()) | _ -> None - let resultInt = Array.tryPick funcInt intArr + let resultInt = tryPickInt funcInt intArr if resultInt <> Some "3" then Assert.Fail() // string array @@ -974,20 +973,26 @@ type ArrayModule() = match x with | "good" -> Some (x.ToString()) | _ -> None - let resultStr = Array.tryPick funcStr strArr + let resultStr = tryPickString funcStr strArr if resultStr <> None then Assert.Fail() // empty array let emptyArr:int[] = [| |] - let resultEpt = Array.tryPick funcInt emptyArr + let resultEpt = tryPickInt funcInt emptyArr if resultEpt <> None then Assert.Fail() // null array let nullArr = null:string[] - CheckThrowsArgumentNullException (fun () -> Array.tryPick funcStr nullArr |> ignore) + CheckThrowsArgumentNullException (fun () -> tryPickString funcStr nullArr |> ignore) () + [] + member this.TryPick() = this.TryPickTester Array.tryPick Array.tryPick + + [] + member this.ParallelTryPick() = this.TryPickTester Array.Parallel.tryPick Array.Parallel.tryPick + [] member this.Fold() = // integer array diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs index 23510ddb781..119edd7c369 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs @@ -972,25 +972,31 @@ type ArrayModule2() = () - [] - member this.TryFind() = + member private _.TryFindTester tryFindInts tryFindStrings = // integer array - let resultInt = [|1..10|] |> Array.tryFind (fun x -> x%7 = 0) + let resultInt = [|1..10|] |> tryFindInts (fun x -> x%7 = 0) if resultInt <> Some 7 then Assert.Fail() // string array - let resultStr = [|"Lists"; "are"; "commonly" ; "list" |] |> Array.tryFind (fun (x:string) -> x.Length > 4) + let resultStr = [|"Lists"; "are"; "commonly" ; "list" |] |> tryFindStrings (fun (x:string) -> x.Length > 4) if resultStr <> Some "Lists" then Assert.Fail() // empty array - let resultEpt =[||] |> Array.tryFind (fun x -> x%7 = 0) + let resultEpt =[||] |> tryFindInts (fun x -> x%7 = 0) if resultEpt <> None then Assert.Fail() // null array let nullArr = null:string[] - CheckThrowsArgumentNullException (fun () -> Array.tryFind (fun (x:string) -> x.Length > 4) nullArr |> ignore) + CheckThrowsArgumentNullException (fun () -> tryFindStrings (fun (x:string) -> x.Length > 4) nullArr |> ignore) () + + [] + member this.TryFind() = this.TryFindTester Array.tryFind Array.tryFind + + [] + member this.ParallelTryFind() = this.TryFindTester Array.Parallel.tryFind Array.Parallel.tryFind + [] member this.TryFindBack() = @@ -1017,25 +1023,32 @@ type ArrayModule2() = () [] - member this.TryFindIndex() = + member private _.TryFindIndexTester tryFindIdxInt tryFindIdxString = // integer array - let resultInt = [|1..10|] |> Array.tryFindIndex (fun x -> x%7 = 0) + let resultInt = [|1..10|] |> tryFindIdxInt (fun x -> x%7 = 0) if resultInt <> Some 6 then Assert.Fail() // string array - let resultStr = [|"Lists"; "are"; "commonly" ; "list" |] |> Array.tryFindIndex (fun (x:string) -> x.Length > 4) + let resultStr = [|"Lists"; "are"; "commonly" ; "list" |] |> tryFindIdxString (fun (x:string) -> x.Length > 4) if resultStr <> Some 0 then Assert.Fail() // empty array - let resultEpt =[||] |> Array.tryFindIndex (fun x -> x % 7 = 0) + let resultEpt =[||] |> tryFindIdxInt (fun x -> x % 7 = 0) if resultEpt <> None then Assert.Fail() // null array let nullArr = null:string[] - CheckThrowsArgumentNullException (fun () -> Array.tryFindIndex (fun (x:string) -> x.Length > 4) nullArr |> ignore) + CheckThrowsArgumentNullException (fun () -> tryFindIdxString (fun (x:string) -> x.Length > 4) nullArr |> ignore) () + [] + member this.TryFindIndex() = this.TryFindIndexTester Array.tryFindIndex Array.tryFindIndex + + [] + member this.ParallelTryFindIndex() = this.TryFindIndexTester Array.Parallel.tryFindIndex Array.Parallel.tryFindIndex + + [] member this.TryFindIndexBack() = // integer array diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs index 1560c16b564..0494f9682d4 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs @@ -14,6 +14,9 @@ let consistency name sqs ls arr = (sqs = arr) |@ (sprintf "Seq.%s = '%A', Array.%s = '%A'" name sqs name arr) .&. (ls = arr) |@ (sprintf "List.%s = '%A', Array.%s = '%A'" name ls name arr) +let consistencyIncludingParallel name sqs ls arr paraArr = + consistency name sqs ls arr .&. + (paraArr = arr) |@ (sprintf "Parallel.%s = '%A', Array.%s = '%A'" name paraArr name arr) let allPairs<'a when 'a : equality> (xs : list<'a>) (xs2 : list<'a>) = let s = xs |> Seq.allPairs xs2 |> Seq.toArray @@ -1104,7 +1107,8 @@ let tryFind<'a when 'a : equality> (xs : 'a []) predicate = let s = xs |> Seq.tryFind predicate let l = xs |> List.ofArray |> List.tryFind predicate let a = xs |> Array.tryFind predicate - consistency "tryFind" s l a + let pa = xs |> Array.Parallel.tryFind predicate + consistencyIncludingParallel "tryFind" s l a pa [] let ``tryFind is consistent`` () = @@ -1128,7 +1132,8 @@ let tryFindIndex<'a when 'a : equality> (xs : 'a []) predicate = let s = xs |> Seq.tryFindIndex predicate let l = xs |> List.ofArray |> List.tryFindIndex predicate let a = xs |> Array.tryFindIndex predicate - consistency "tryFindIndex" s l a + let pa = xs |> Array.Parallel.tryFindIndex predicate + consistencyIncludingParallel "tryFindIndex" s l a pa [] let ``tryFindIndex is consistent`` () = @@ -1188,7 +1193,8 @@ let tryPick<'a when 'a : comparison> (xs : 'a []) f = let s = xs |> Seq.tryPick f let l = xs |> List.ofArray |> List.tryPick f let a = xs |> Array.tryPick f - consistency "tryPick" s l a + let pa = xs |> Array.Parallel.tryPick f + consistencyIncludingParallel "tryPick" s l a pa [] let ``tryPick is consistent`` () = From dae90b0cc89111a356660bdf376dbafd073de8a5 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 9 Mar 2023 14:59:17 +0100 Subject: [PATCH 5/8] Adding [] --- src/FSharp.Core/array.fsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/FSharp.Core/array.fsi b/src/FSharp.Core/array.fsi index 7bf6b50544c..0eb9575fd9e 100644 --- a/src/FSharp.Core/array.fsi +++ b/src/FSharp.Core/array.fsi @@ -3122,6 +3122,7 @@ module Array = /// Evaluates to None /// [] + [] val tryFind: predicate:('T -> bool) -> array:'T[] -> 'T option @@ -3153,6 +3154,7 @@ module Array = /// Evaluates to None /// [] + [] val tryFindIndex : predicate:('T -> bool) -> array:'T[] -> int option /// Applies the given function to successive elements, returning the first @@ -3185,6 +3187,7 @@ module Array = /// /// [] + [] val tryPick: chooser:('T -> 'U option) -> array:'T[] -> 'U option /// Apply the given function to each element of the array. Return From e77751c6e06f1ceee5279d2c7b31e58c30817220 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 9 Mar 2023 15:00:16 +0100 Subject: [PATCH 6/8] ups --- .../FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs index 119edd7c369..cd861209087 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs @@ -1022,7 +1022,6 @@ type ArrayModule2() = () - [] member private _.TryFindIndexTester tryFindIdxInt tryFindIdxString = // integer array let resultInt = [|1..10|] |> tryFindIdxInt (fun x -> x%7 = 0) From c00f95ba6049599b1c83e6e1a6e28e5a44b14ef0 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 10 Mar 2023 15:59:39 +0100 Subject: [PATCH 7/8] Apply suggestions from code review Co-authored-by: Petr --- src/FSharp.Core/array.fs | 2 +- src/FSharp.Core/array.fsi | 10 +++++----- .../Microsoft.FSharp.Collections/ArrayModule2.fs | 2 -- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/FSharp.Core/array.fs b/src/FSharp.Core/array.fs index d478d2d23f0..2e8926ec6c6 100644 --- a/src/FSharp.Core/array.fs +++ b/src/FSharp.Core/array.fs @@ -1951,7 +1951,7 @@ module Array = [] let tryFind predicate (array: _[]) = - array |> tryFindIndex predicate |> Option.map (fun i -> array.[i]) + array |> tryFindIndex predicate |> Option.map (fun i -> array[i]) [] let tryPick chooser (array: _[]) = diff --git a/src/FSharp.Core/array.fsi b/src/FSharp.Core/array.fsi index 0eb9575fd9e..4f4005f5915 100644 --- a/src/FSharp.Core/array.fsi +++ b/src/FSharp.Core/array.fsi @@ -3094,8 +3094,8 @@ module Array = /// Provides parallel operations on arrays module Parallel = - /// Returns the first element for which the given function returns True. - /// Return None if no such element exists. + /// Returns the first element for which the given function returns True. + /// Returns None if no such element exists. /// /// The function to test the input elements. /// The input array. @@ -3110,7 +3110,7 @@ module Array = /// /// inputs |> Array.Parallel.tryFind (fun elm -> elm % 2 = 0) /// - /// Evaluates to Some 2 + /// Evaluates to Some 2. /// /// /// Try to find the first even number: @@ -3128,7 +3128,7 @@ module Array = /// Returns the index of the first element in the array /// that satisfies the given predicate. - /// + /// Returns None if no such element exists. /// The function to test the input elements. /// The input array. /// @@ -3174,7 +3174,7 @@ module Array = /// /// input |> Array.Parallel.tryPick (fun n -> if n % 2 = 0 then Some (string n) else None) /// - /// Evaluates to Some "2". + /// Evaluates to Some 2. /// /// /// diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs index cd861209087..b10ce17fb2e 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs @@ -1046,8 +1046,6 @@ type ArrayModule2() = [] member this.ParallelTryFindIndex() = this.TryFindIndexTester Array.Parallel.tryFindIndex Array.Parallel.tryFindIndex - - [] member this.TryFindIndexBack() = // integer array From 987ec596f976ac8fcef516e0f2c8d7ca269f7392 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 13 Mar 2023 18:02:44 +0100 Subject: [PATCH 8/8] Update src/FSharp.Core/array.fsi --- src/FSharp.Core/array.fsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FSharp.Core/array.fsi b/src/FSharp.Core/array.fsi index 4f4005f5915..d05ecacc0b3 100644 --- a/src/FSharp.Core/array.fsi +++ b/src/FSharp.Core/array.fsi @@ -3127,7 +3127,7 @@ module Array = /// Returns the index of the first element in the array - /// that satisfies the given predicate. + /// that satisfies the given predicate. /// Returns None if no such element exists. /// The function to test the input elements. /// The input array.