1
+ package scala
2
+ import reflect .ClassTag
3
+
4
+ /** An immutable array. An `IArray[T]` has the same representation as an `Array[T]`,
5
+ * but it cannot be updated. Unlike regular arrays, immutable arrays are covariant.
6
+ */
7
+ opaque type IArray [+ T ] = Array [_ <: T ]
8
+
9
+ object IArray {
10
+
11
+ /** Defines extension methods for immutable arrays */
12
+ implied arrayOps {
13
+
14
+ /** The selection operation on an immutable array.
15
+ *
16
+ * @param arr the immutable array
17
+ * @param n the index of the element to select
18
+ * @return the element of the array at the given index
19
+ */
20
+ inline def (arr : IArray [T ]) apply[T ] (n : Int ): T = arr.asInstanceOf [Array [T ]].apply(n)
21
+
22
+ /** The number of elements in an immutable array
23
+ * @param arr the immutable array
24
+ */
25
+ inline def (arr : IArray [T ]) length[T ] : Int = arr.asInstanceOf [Array [T ]].length
26
+ }
27
+
28
+ /** An immutable array of length 0.
29
+ */
30
+ def empty [T : ClassTag ]: IArray [T ] = new Array [T ](0 )
31
+
32
+ /** An immutable array with given elements.
33
+ */
34
+ def apply [T : ClassTag ](xs : T * ): IArray [T ] = Array (xs : _* )
35
+ def apply (x : Boolean , xs : Boolean * ): IArray [Boolean ] = Array (x, xs : _* )
36
+ def apply (x : Byte , xs : Byte * ): IArray [Byte ] = Array (x, xs : _* )
37
+ def apply (x : Short , xs : Short * ): IArray [Short ] = Array (x, xs : _* )
38
+ def apply (x : Char , xs : Char * ): IArray [Char ] = Array (x, xs : _* )
39
+ def apply (x : Int , xs : Int * ): IArray [Int ] = Array (x, xs : _* )
40
+ def apply (x : Long , xs : Long * ): IArray [Long ] = Array (x, xs : _* )
41
+ def apply (x : Float , xs : Float * ): IArray [Float ] = Array (x, xs : _* )
42
+ def apply (x : Double , xs : Double * ): IArray [Double ] = Array (x, xs : _* )
43
+ def apply (x : Unit , xs : Unit * ): IArray [Unit ] = Array (x, xs : _* )
44
+
45
+ /** Concatenates all arrays into a single immutable array.
46
+ *
47
+ * @param xss the given immutable arrays
48
+ * @return the array created from concatenating `xss`
49
+ */
50
+ def concat [T : ClassTag ](xss : IArray [T ]* ): IArray [T ] = Array .concat[T ](xss.asInstanceOf [Seq [Array [T ]]]: _* )
51
+
52
+ /** Returns an immutable array that contains the results of some element computation a number
53
+ * of times. Each element is determined by a separate computation.
54
+ *
55
+ * @param n the number of elements in the array
56
+ * @param elem the element computation
57
+ */
58
+ def fill [T : ClassTag ](n : Int )(elem : => T ): IArray [T ] =
59
+ Array .fill(n)(elem)
60
+
61
+ /** Returns a two-dimensional immutable array that contains the results of some element computation a number
62
+ * of times. Each element is determined by a separate computation.
63
+ *
64
+ * @param n1 the number of elements in the 1st dimension
65
+ * @param n2 the number of elements in the 2nd dimension
66
+ * @param elem the element computation
67
+ */
68
+ def fill [T : ClassTag ](n1 : Int , n2 : Int )(elem : => T ): IArray [IArray [T ]] =
69
+ Array .fill(n1, n2)(elem)
70
+
71
+ /** Returns a three-dimensional immutable array that contains the results of some element computation a number
72
+ * of times. Each element is determined by a separate computation.
73
+ *
74
+ * @param n1 the number of elements in the 1st dimension
75
+ * @param n2 the number of elements in the 2nd dimension
76
+ * @param n3 the number of elements in the 3nd dimension
77
+ * @param elem the element computation
78
+ */
79
+ def fill [T : ClassTag ](n1 : Int , n2 : Int , n3 : Int )(elem : => T ): IArray [IArray [IArray [T ]]] =
80
+ Array .fill(n1, n2, n3)(elem)
81
+
82
+ /** Returns a four-dimensional immutable array that contains the results of some element computation a number
83
+ * of times. Each element is determined by a separate computation.
84
+ *
85
+ * @param n1 the number of elements in the 1st dimension
86
+ * @param n2 the number of elements in the 2nd dimension
87
+ * @param n3 the number of elements in the 3nd dimension
88
+ * @param n4 the number of elements in the 4th dimension
89
+ * @param elem the element computation
90
+ */
91
+ def fill [T : ClassTag ](n1 : Int , n2 : Int , n3 : Int , n4 : Int )(elem : => T ): IArray [IArray [IArray [IArray [T ]]]] =
92
+ Array .fill(n1, n2, n3, n4)(elem)
93
+
94
+ /** Returns a five-dimensional immutable array that contains the results of some element computation a number
95
+ * of times. Each element is determined by a separate computation.
96
+ *
97
+ * @param n1 the number of elements in the 1st dimension
98
+ * @param n2 the number of elements in the 2nd dimension
99
+ * @param n3 the number of elements in the 3nd dimension
100
+ * @param n4 the number of elements in the 4th dimension
101
+ * @param n5 the number of elements in the 5th dimension
102
+ * @param elem the element computation
103
+ */
104
+ def fill [T : ClassTag ](n1 : Int , n2 : Int , n3 : Int , n4 : Int , n5 : Int )(elem : => T ): IArray [IArray [IArray [IArray [IArray [T ]]]]] =
105
+ Array .fill(n1, n2, n3, n4, n5)(elem)
106
+
107
+ /** Returns an immutable array containing values of a given function over a range of integer
108
+ * values starting from 0.
109
+ *
110
+ * @param n The number of elements in the array
111
+ * @param f The function computing element values
112
+ */
113
+ def tabulate [T : ClassTag ](n : Int )(f : Int => T ): IArray [T ] =
114
+ Array .tabulate(n)(f)
115
+
116
+ /** Returns a two-dimensional immutable array containing values of a given function
117
+ * over ranges of integer values starting from `0`.
118
+ *
119
+ * @param n1 the number of elements in the 1st dimension
120
+ * @param n2 the number of elements in the 2nd dimension
121
+ * @param f The function computing element values
122
+ */
123
+ def tabulate [T : ClassTag ](n1 : Int , n2 : Int )(f : (Int , Int ) => T ): IArray [IArray [T ]] =
124
+ Array .tabulate(n1, n2)(f)
125
+
126
+ /** Returns a three-dimensional immutable array containing values of a given function
127
+ * over ranges of integer values starting from `0`.
128
+ *
129
+ * @param n1 the number of elements in the 1st dimension
130
+ * @param n2 the number of elements in the 2nd dimension
131
+ * @param n3 the number of elements in the 3rd dimension
132
+ * @param f The function computing element values
133
+ */
134
+ def tabulate [T : ClassTag ](n1 : Int , n2 : Int , n3 : Int )(f : (Int , Int , Int ) => T ): IArray [IArray [IArray [T ]]] =
135
+ Array .tabulate(n1, n2, n3)(f)
136
+
137
+ /** Returns a four-dimensional immutable array containing values of a given function
138
+ * over ranges of integer values starting from `0`.
139
+ *
140
+ * @param n1 the number of elements in the 1st dimension
141
+ * @param n2 the number of elements in the 2nd dimension
142
+ * @param n3 the number of elements in the 3rd dimension
143
+ * @param n4 the number of elements in the 4th dimension
144
+ * @param f The function computing element values
145
+ */
146
+ def tabulate [T : ClassTag ](n1 : Int , n2 : Int , n3 : Int , n4 : Int )(f : (Int , Int , Int , Int ) => T ): IArray [IArray [IArray [IArray [T ]]]] =
147
+ Array .tabulate(n1, n2, n3, n4)(f)
148
+
149
+ /** Returns a five-dimensional immutable array containing values of a given function
150
+ * over ranges of integer values starting from `0`.
151
+ *
152
+ * @param n1 the number of elements in the 1st dimension
153
+ * @param n2 the number of elements in the 2nd dimension
154
+ * @param n3 the number of elements in the 3rd dimension
155
+ * @param n4 the number of elements in the 4th dimension
156
+ * @param n5 the number of elements in the 5th dimension
157
+ * @param f The function computing element values
158
+ */
159
+ def tabulate [T : ClassTag ](n1 : Int , n2 : Int , n3 : Int , n4 : Int , n5 : Int )(f : (Int , Int , Int , Int , Int ) => T ): IArray [IArray [IArray [IArray [IArray [T ]]]]] =
160
+ Array .tabulate(n1, n2, n3, n4, n5)(f)
161
+
162
+ /** Returns an immutable array containing a sequence of increasing integers in a range.
163
+ *
164
+ * @param start the start value of the array
165
+ * @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned)
166
+ * @return the immutable array with values in range `start, start + 1, ..., end - 1`
167
+ * up to, but excluding, `end`.
168
+ */
169
+ def range (start : Int , end : Int ): IArray [Int ] = Array .range(start, end)
170
+
171
+ /** Returns an immutable array containing equally spaced values in some integer interval.
172
+ *
173
+ * @param start the start value of the array
174
+ * @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned)
175
+ * @param step the increment value of the array (may not be zero)
176
+ * @return the immutable array with values in `start, start + step, ...` up to, but excluding `end`
177
+ */
178
+ def range (start : Int , end : Int , step : Int ): IArray [Int ] = Array .range(start, end, step)
179
+
180
+ /** Returns an immutable array containing repeated applications of a function to a start value.
181
+ *
182
+ * @param start the start value of the array
183
+ * @param len the number of elements returned by the array
184
+ * @param f the function that is repeatedly applied
185
+ * @return the immutable array returning `len` values in the sequence `start, f(start), f(f(start)), ...`
186
+ */
187
+ def iterate [T : ClassTag ](start : T , len : Int )(f : T => T ): IArray [T ] = Array .iterate(start, len)(f)
188
+
189
+ /** Returns a decomposition of the array into a sequence. This supports
190
+ * a pattern match like `{ case IArray(x,y,z) => println('3 elements')}`.
191
+ *
192
+ * @param x the selector value
193
+ * @return sequence wrapped in a [[scala.Some ]], if `x` is a Seq, otherwise `None`
194
+ */
195
+ def unapplySeq [T ](x : IArray [T ]) = Array .unapplySeq[T ](x.asInstanceOf [Array [T ]])
196
+ }
0 commit comments