@@ -1006,3 +1006,201 @@ let isDefault (array : FlatList<'T>) = array.IsDefault
10061006
10071007[<CompiledName " IsDefaultOrEmpty" >]
10081008let isDefaultOrEmpty ( array : FlatList < 'T >) = array.IsDefaultOrEmpty
1009+
1010+ // Most functions unwrap the underlying array without a copy, call the Array.Parallel function, and wrap its fresh result
1011+ // without a copy (ADR 0001, D11), so that they have the semantics and the exceptions of Array.Parallel. Where the
1012+ // Array.Parallel function takes or returns options or builds a tuple per element or per group (choose, tryFind,
1013+ // tryFindIndex, tryPick, zip, groupBy), an algorithm of ParallelArrays with value options and struct tuples runs instead.
1014+ // Array.Parallel sorts a copy of its input, so the shared array is never changed.
1015+ [<RequireQualifiedAccess>]
1016+ module Parallel =
1017+
1018+ // ---- Creation ----
1019+
1020+ [<CompiledName " Initialize" >]
1021+ let init count ( initializer : int -> 'T ) = Array.Parallel.init count initializer |> wrapArray
1022+
1023+ // ---- Search ----
1024+
1025+ [<CompiledName " Exists" >]
1026+ let exists predicate ( array : FlatList < 'T >) = Array.Parallel.exists predicate ( unwrapArray ( nameof array) array)
1027+
1028+ [<CompiledName " ForAll" >]
1029+ let forall predicate ( array : FlatList < 'T >) = Array.Parallel.forall predicate ( unwrapArray ( nameof array) array)
1030+
1031+ [<CompiledName " TryFind" >]
1032+ let tryFind predicate ( array : FlatList < 'T >) =
1033+ let source = unwrapArray ( nameof array) array
1034+
1035+ match ParallelArrays.tryFindIndex predicate source with
1036+ | ValueSome index -> ValueSome source[ index]
1037+ | ValueNone -> ValueNone
1038+
1039+ [<CompiledName " TryFindIndex" >]
1040+ let tryFindIndex predicate ( array : FlatList < 'T >) = ParallelArrays.tryFindIndex predicate ( unwrapArray ( nameof array) array)
1041+
1042+ [<CompiledName " TryPick" >]
1043+ let tryPick ( chooser : 'T -> 'U voption ) ( array : FlatList < 'T >) =
1044+ ParallelArrays.tryPick chooser ( unwrapArray ( nameof array) array)
1045+
1046+ // ---- Transformation ----
1047+
1048+ [<CompiledName " Choose" >]
1049+ let choose ( chooser : 'T -> 'U voption ) ( array : FlatList < 'T >) =
1050+ ParallelArrays.choose chooser ( unwrapArray ( nameof array) array)
1051+ |> wrapArray
1052+
1053+ [<CompiledName " Collect" >]
1054+ let collect ( mapping : 'T -> FlatList < 'U >) ( array : FlatList < 'T >) =
1055+ // As in Array.Parallel.collect, the mapping runs in parallel, and the results are copied in their order into one
1056+ // array of their total length. Array.Parallel.collect dereferences a null result; a default flat list from the
1057+ // mapping throws ArgumentNullException instead, as in the sequential collect (ADR 0001, D6).
1058+ let results = Array.Parallel.map mapping ( unwrapArray ( nameof array) array)
1059+ let mutable length = 0
1060+
1061+ for result in results do
1062+ checkNotDefault ( nameof mapping) result
1063+ length <- length + result.Length
1064+
1065+ let builder = ImmutableArray.CreateBuilder< 'U> length
1066+
1067+ for result in results do
1068+ builder.AddRange result
1069+
1070+ builder.MoveToImmutable ()
1071+
1072+ [<CompiledName " Filter" >]
1073+ let filter predicate ( array : FlatList < 'T >) =
1074+ Array.Parallel.filter predicate ( unwrapArray ( nameof array) array)
1075+ |> wrapArray
1076+
1077+ [<CompiledName " Map" >]
1078+ let map ( mapping : 'T -> 'U ) ( array : FlatList < 'T >) =
1079+ Array.Parallel.map mapping ( unwrapArray ( nameof array) array)
1080+ |> wrapArray
1081+
1082+ [<CompiledName " MapIndexed" >]
1083+ let mapi ( mapping : int -> 'T -> 'U ) ( array : FlatList < 'T >) =
1084+ Array.Parallel.mapi mapping ( unwrapArray ( nameof array) array)
1085+ |> wrapArray
1086+
1087+ [<CompiledName " Zip" >]
1088+ let zip ( array1 : FlatList < 'T1 >) ( array2 : FlatList < 'T2 >) =
1089+ let source1 = unwrapArray ( nameof array1) array1
1090+ let source2 = unwrapArray ( nameof array2) array2
1091+ ArrayChecks.sameLengths ( nameof array1) source1 ( nameof array2) source2
1092+ ParallelArrays.zip structPair source1 source2 |> wrapArray
1093+
1094+ // ---- Folding ----
1095+
1096+ // The inline functions can use public members only, so they check and unwrap the array themselves
1097+ [<CompiledName " Average" >]
1098+ let inline average ( array : FlatList < ^T >) : ^T =
1099+ if array.IsDefault then
1100+ nullArg ( nameof array)
1101+
1102+ Array.Parallel.average (
1103+ ImmutableCollectionsMarshal.AsArray array
1104+ |> Unchecked.nonNull
1105+ )
1106+
1107+ [<CompiledName " AverageBy" >]
1108+ let inline averageBy ( [<InlineIfLambda>] projection : 'T -> ^U ) ( array : FlatList < 'T >) : ^U =
1109+ if array.IsDefault then
1110+ nullArg ( nameof array)
1111+
1112+ Array.Parallel.averageBy
1113+ projection
1114+ ( ImmutableCollectionsMarshal.AsArray array
1115+ |> Unchecked.nonNull)
1116+
1117+ [<CompiledName " Iterate" >]
1118+ let iter action ( array : FlatList < 'T >) = Array.Parallel.iter action ( unwrapArray ( nameof array) array)
1119+
1120+ [<CompiledName " IterateIndexed" >]
1121+ let iteri action ( array : FlatList < 'T >) = Array.Parallel.iteri action ( unwrapArray ( nameof array) array)
1122+
1123+ [<CompiledName " Max" >]
1124+ let max ( array : FlatList < 'T >) = Array.Parallel.max ( unwrapArray ( nameof array) array)
1125+
1126+ [<CompiledName " MaxBy" >]
1127+ let maxBy ( projection : 'T -> 'U ) ( array : FlatList < 'T >) = Array.Parallel.maxBy projection ( unwrapArray ( nameof array) array)
1128+
1129+ [<CompiledName " Min" >]
1130+ let min ( array : FlatList < 'T >) = Array.Parallel.min ( unwrapArray ( nameof array) array)
1131+
1132+ [<CompiledName " MinBy" >]
1133+ let minBy ( projection : 'T -> 'U ) ( array : FlatList < 'T >) = Array.Parallel.minBy projection ( unwrapArray ( nameof array) array)
1134+
1135+ [<CompiledName " Reduce" >]
1136+ let reduce reduction ( array : FlatList < 'T >) = Array.Parallel.reduce reduction ( unwrapArray ( nameof array) array)
1137+
1138+ [<CompiledName " ReduceBy" >]
1139+ let reduceBy ( projection : 'T -> 'U ) reduction ( array : FlatList < 'T >) =
1140+ Array.Parallel.reduceBy projection reduction ( unwrapArray ( nameof array) array)
1141+
1142+ // Array.Parallel.sum dereferences a null array without a check; a default flat list throws ArgumentNullException,
1143+ // which its documentation promises
1144+ [<CompiledName " Sum" >]
1145+ let inline sum ( array : FlatList < ^T >) : ^T =
1146+ if array.IsDefault then
1147+ nullArg ( nameof array)
1148+
1149+ Array.Parallel.sum (
1150+ ImmutableCollectionsMarshal.AsArray array
1151+ |> Unchecked.nonNull
1152+ )
1153+
1154+ [<CompiledName " SumBy" >]
1155+ let inline sumBy ( [<InlineIfLambda>] projection : 'T -> ^U ) ( array : FlatList < 'T >) : ^U =
1156+ if array.IsDefault then
1157+ nullArg ( nameof array)
1158+
1159+ Array.Parallel.sumBy
1160+ projection
1161+ ( ImmutableCollectionsMarshal.AsArray array
1162+ |> Unchecked.nonNull)
1163+
1164+ // ---- Partitioning and grouping ----
1165+
1166+ [<CompiledName " GroupBy" >]
1167+ let groupBy ( projection : 'T -> 'Key ) ( array : FlatList < 'T >) =
1168+ ParallelArrays.groupBy ( fun key items -> struct ( key, wrapArray items)) projection ( unwrapArray ( nameof array) array)
1169+ |> wrapArray
1170+
1171+ [<CompiledName " Partition" >]
1172+ let partition predicate ( array : FlatList < 'T >) =
1173+ let accepted , rejected = Array.Parallel.partition predicate ( unwrapArray ( nameof array) array)
1174+ struct ( wrapArray accepted, wrapArray rejected)
1175+
1176+ [<CompiledName " PartitionWith" >]
1177+ let partitionWith ( partitioner : 'T -> Choice < 'T1 , 'T2 >) ( array : FlatList < 'T >) =
1178+ let first , second = Array.Parallel.partitionWith partitioner ( unwrapArray ( nameof array) array)
1179+ struct ( wrapArray first, wrapArray second)
1180+
1181+ // ---- Sorting ----
1182+
1183+ [<CompiledName " Sort" >]
1184+ let sort ( array : FlatList < 'T >) =
1185+ Array.Parallel.sort ( unwrapArray ( nameof array) array)
1186+ |> wrapArray
1187+
1188+ [<CompiledName " SortBy" >]
1189+ let sortBy ( projection : 'T -> 'Key ) ( array : FlatList < 'T >) =
1190+ Array.Parallel.sortBy projection ( unwrapArray ( nameof array) array)
1191+ |> wrapArray
1192+
1193+ [<CompiledName " SortByDescending" >]
1194+ let sortByDescending ( projection : 'T -> 'Key ) ( array : FlatList < 'T >) =
1195+ Array.Parallel.sortByDescending projection ( unwrapArray ( nameof array) array)
1196+ |> wrapArray
1197+
1198+ [<CompiledName " SortDescending" >]
1199+ let sortDescending ( array : FlatList < 'T >) =
1200+ Array.Parallel.sortDescending ( unwrapArray ( nameof array) array)
1201+ |> wrapArray
1202+
1203+ [<CompiledName " SortWith" >]
1204+ let sortWith comparer ( array : FlatList < 'T >) =
1205+ Array.Parallel.sortWith comparer ( unwrapArray ( nameof array) array)
1206+ |> wrapArray
0 commit comments