88/// ` structPair ` or ` structTriple ` and the function of ` Tuple.FlatList ` with ` referencePair ` or ` referenceTriple ` , so
99/// that it exists once. For 10 000 elements, ` zip ` of struct tuples allocates 80 KB where ` Array.zip ` followed by a
1010/// conversion allocates 400 KB.
11+ /// The first sentences of the comment of each function are the summary of the function of the FSharp.Core ` Array ` module
12+ /// word for word (FSharp.Core 10.1), and the sentences after them say what differs and why the function exists.
1113module internal FSharp.Collections.Immutable.Arrays
1214
1315open System
1416open System.Collections .Generic
1517open System.Linq
1618
17- /// The pairs of every element of ` array1 ` with every element of ` array2 ` .
18- /// It exists because ` Array.allPairs ` returns reference tuples. ` FlatList.allPairs ` builds struct tuples with it
19- /// directly (720 KB for 300 by 300 elements, where ` Array.allPairs ` followed by a conversion allocates 3.6 MB).
19+ /// Returns a new array that contains all pairings of elements from the first and second arrays.
20+ /// The pairs are built with ` tuple ` . It exists because ` Array.allPairs ` returns reference tuples. ` FlatList.allPairs `
21+ /// builds struct tuples with it directly (720 KB for 300 by 300 elements, where ` Array.allPairs ` followed by a conversion
22+ /// allocates 3.6 MB).
2023let inline allPairs ( [<InlineIfLambda>] tuple : 'T1 -> 'T2 -> 'R ) ( array1 : 'T1 array ) ( array2 : 'T2 array ) : 'R array =
2124 let length2 = array2.Length
2225 let result = Array.zeroCreate ( array1.Length * length2)
@@ -27,7 +30,7 @@ let inline allPairs ([<InlineIfLambda>] tuple : 'T1 -> 'T2 -> 'R) (array1 : 'T1
2730
2831 result
2932
30- /// A key that may be null, for a dictionary, which rejects null keys.
33+ /// A key that may be null, for a dictionary, which rejects null keys. FSharp.Core has no such type in its public API.
3134/// It exists because ` Array.countBy ` and ` Array.groupBy ` accept a null key (` [| null; "a"; null |] ` has two keys), and
3235/// ` Dictionary ` throws ` ArgumentNullException ` for one.
3336[<Struct>]
@@ -45,9 +48,11 @@ let nullableKeyComparer<'Key when 'Key : equality> () =
4548 member _.GetHashCode key = structural.GetHashCode key.Key
4649 }
4750
48- /// The keys of the projection in the order of their first occurrence, each with the number of its elements.
49- /// The counting keeps one counter per key, not the elements, so it needs memory for the keys only.
50- /// It exists because ` Array.countBy ` returns reference tuples; null keys and keys that are arrays work as in FSharp.Core.
51+ /// Applies a key-generating function to each element of an array and returns an array yielding unique keys and their
52+ /// number of occurrences in the original array.
53+ /// The unique keys come in the order of their first occurrence, and the counting keeps one counter per key, not the
54+ /// elements, so it needs memory for the keys only. The tuples are built with ` tuple ` . It exists because ` Array.countBy `
55+ /// returns reference tuples; null keys and keys that are arrays work as in FSharp.Core.
5156let inline countBy
5257 ( [<InlineIfLambda>] tuple : 'Key -> int -> 'R )
5358 ( projection : 'T -> 'Key )
@@ -75,8 +80,11 @@ let inline countBy
7580
7681 result
7782
78- /// The keys of the projection in the order of their first occurrence, each with its elements in their order.
79- /// It exists because ` Array.groupBy ` returns reference tuples. It groups once with a lookup, as the project rules ask.
83+ /// Applies a key-generating function to each element of an array and yields an array of unique keys. Each unique key
84+ /// contains an array of all elements that match to this key.
85+ /// The keys come in the order of their first occurrence, and the elements of a key in their order. The tuples are built
86+ /// with ` tuple ` . It exists because ` Array.groupBy ` returns reference tuples. It groups once with a lookup, as the project
87+ /// rules ask.
8088let inline groupBy
8189 ( [<InlineIfLambda>] tuple : 'Key -> 'T array -> 'R )
8290 ( projection : 'T -> 'Key )
@@ -92,8 +100,10 @@ let inline groupBy
92100
93101 result
94102
95- /// Every element with its index.
96- /// It exists because ` Array.indexed ` returns reference tuples (320 KB for 10 000 elements, where struct tuples take 80 KB).
103+ /// Builds a new array whose elements are the corresponding elements of the input array paired with the integer index
104+ /// (from 0) of each element.
105+ /// The pairs are built with ` tuple ` . It exists because ` Array.indexed ` returns reference tuples (320 KB for 10 000
106+ /// elements, where struct tuples take 80 KB).
97107let inline indexed ( [<InlineIfLambda>] tuple : int -> 'T -> 'R ) ( array : 'T array ) : 'R array =
98108 let result = Array.zeroCreate array.Length
99109
@@ -102,8 +112,10 @@ let inline indexed ([<InlineIfLambda>] tuple : int -> 'T -> 'R) (array : 'T arra
102112
103113 result
104114
105- /// Every element with its successor.
106- /// It exists because ` Array.pairwise ` returns reference tuples.
115+ /// Returns an array of each element in the input array paired with its predecessor, with the exception of the first
116+ /// element which is only returned as the predecessor of the second element. The predecessor comes first in the returned
117+ /// pairs.
118+ /// The pairs are built with ` tuple ` . It exists because ` Array.pairwise ` returns reference tuples.
107119let inline pairwise ( [<InlineIfLambda>] tuple : 'T -> 'T -> 'R ) ( array : 'T array ) : 'R array =
108120 if array.Length < 2 then
109121 Array.Empty ()
@@ -115,10 +127,10 @@ let inline pairwise ([<InlineIfLambda>] tuple : 'T -> 'T -> 'R) (array : 'T arra
115127
116128 result
117129
118- /// Splits the pairs of an array with ` split ` into two arrays.
119- /// It exists because ` Array.unzip ` takes reference tuples. ` FlatList.unzip ` has struct tuples and passes ` id ` as ` split ` ,
120- /// ` Tuple.FlatList.unzip ` has reference tuples and converts one pair at a time, so that no array of converted pairs
121- /// (400 KB for 10 000 pairs) is built.
130+ /// Splits an array of pairs into two arrays.
131+ /// ` split ` reads a pair as a struct tuple. It exists because ` Array.unzip ` takes reference tuples. ` FlatList.unzip ` has
132+ /// struct tuples and passes ` id ` as ` split ` , ` Tuple.FlatList.unzip ` has reference tuples and converts one pair at a time,
133+ /// so that no array of converted pairs (400 KB for 10 000 pairs) is built.
122134let inline unzip ( [<InlineIfLambda>] split : 'P -> struct ( 'T1 * 'T2 )) ( array : 'P array ) =
123135 let result1 = Array.zeroCreate array.Length
124136 let result2 = Array.zeroCreate array.Length
@@ -130,8 +142,8 @@ let inline unzip ([<InlineIfLambda>] split : 'P -> struct ('T1 * 'T2)) (array :
130142
131143 struct ( result1, result2)
132144
133- /// Splits the triples of an array with ` split ` into three arrays.
134- /// It exists for the reason of ` unzip ` : ` Array.unzip3 ` takes reference tuples.
145+ /// Splits an array of triples into three arrays.
146+ /// ` split ` reads a triple as a struct tuple. It exists for the reason of ` unzip ` : ` Array.unzip3 ` takes reference tuples.
135147let inline unzip3 ( [<InlineIfLambda>] split : 'P -> struct ( 'T1 * 'T2 * 'T3 )) ( array : 'P array ) =
136148 let result1 = Array.zeroCreate array.Length
137149 let result2 = Array.zeroCreate array.Length
@@ -145,9 +157,10 @@ let inline unzip3 ([<InlineIfLambda>] split : 'P -> struct ('T1 * 'T2 * 'T3)) (a
145157
146158 struct ( result1, result2, result3)
147159
148- /// Pairs the elements of two arrays of the same length.
149- /// It exists because ` Array.zip ` returns reference tuples (400 KB for 10 000 elements with the conversion, 80 KB here).
150- /// The callers check the lengths first, with the exception of ` Array.zip ` .
160+ /// Combines the two arrays into an array of pairs. The two arrays must have equal lengths, otherwise an ArgumentException
161+ /// is raised.
162+ /// The pairs are built with ` tuple ` , and the callers check the lengths first and raise the exception of ` Array.zip ` . It
163+ /// exists because ` Array.zip ` returns reference tuples (400 KB for 10 000 elements with the conversion, 80 KB here).
151164let inline zip ( [<InlineIfLambda>] tuple : 'T1 -> 'T2 -> 'R ) ( array1 : 'T1 array ) ( array2 : 'T2 array ) : 'R array =
152165 let result = Array.zeroCreate array1.Length
153166
@@ -156,8 +169,10 @@ let inline zip ([<InlineIfLambda>] tuple : 'T1 -> 'T2 -> 'R) (array1 : 'T1 array
156169
157170 result
158171
159- /// Combines the elements of three arrays of the same length.
160- /// It exists for the reason of ` zip ` : ` Array.zip3 ` returns reference tuples. The callers check the lengths first.
172+ /// Combines three arrays into an array of triples. The three arrays must have equal lengths, otherwise an
173+ /// ArgumentException is raised. (The summary of ` Array.zip3 ` says "an array of pairs", which is a slip.)
174+ /// The triples are built with ` tuple ` , and the callers check the lengths first. It exists for the reason of ` zip ` :
175+ /// ` Array.zip3 ` returns reference tuples.
161176let inline zip3
162177 ( [<InlineIfLambda>] tuple : 'T1 -> 'T2 -> 'T3 -> 'R )
163178 ( array1 : 'T1 array )
0 commit comments