0
|
1 package fj.data.vector;
|
|
2
|
|
3 import fj.F;
|
|
4 import fj.F2;
|
|
5 import fj.P1;
|
|
6 import fj.P2;
|
|
7 import fj.P3;
|
|
8 import fj.P4;
|
|
9 import static fj.Function.curry;
|
|
10 import static fj.P.p2;
|
|
11 import fj.data.Array;
|
|
12 import fj.data.NonEmptyList;
|
|
13 import fj.data.Stream;
|
|
14
|
|
15 import java.util.Iterator;
|
|
16
|
|
17 /**
|
|
18 * A vector-4.
|
|
19 */
|
|
20 public final class V4<A> implements Iterable<A> {
|
|
21
|
|
22 private final V3<A> tail;
|
|
23 private final P1<A> head;
|
|
24
|
|
25 private V4(final P1<A> head, final V3<A> tail) {
|
|
26 this.head = head;
|
|
27 this.tail = tail;
|
|
28 }
|
|
29
|
|
30 /**
|
|
31 * Creates a vector-4 from a homogeneous product-4.
|
|
32 *
|
|
33 * @param p The product-4 from which to create a vector.
|
|
34 * @return A new vector-4.
|
|
35 */
|
|
36 public static <A> V4<A> p(final P4<A, A, A, A> p) {
|
|
37 return new V4<A>(new P1<A>() {
|
|
38 public A _1() {
|
|
39 return p._1();
|
|
40 }
|
|
41 }, V3.p(new P3<A, A, A>() {
|
|
42 public A _1() {
|
|
43 return p._2();
|
|
44 }
|
|
45
|
|
46 public A _2() {
|
|
47 return p._3();
|
|
48 }
|
|
49
|
|
50 public A _3() {
|
|
51 return p._4();
|
|
52 }
|
|
53 }));
|
|
54 }
|
|
55
|
|
56 /**
|
|
57 * Creates a vector-4 from a head and a tail.
|
|
58 *
|
|
59 * @param head The value to put as the first element of the vector.
|
|
60 * @param tail The vector representing all but the first element of the new vector.
|
|
61 * @return The new vector.
|
|
62 */
|
|
63 public static <A> V4<A> cons(final P1<A> head, final V3<A> tail) {
|
|
64 return new V4<A>(head, tail);
|
|
65 }
|
|
66
|
|
67 /**
|
|
68 * Returns the first element of this vector.
|
|
69 *
|
|
70 * @return the first element of this vector.
|
|
71 */
|
|
72 public A _1() {
|
|
73 return head._1();
|
|
74 }
|
|
75
|
|
76 /**
|
|
77 * Returns the second element of this vector.
|
|
78 *
|
|
79 * @return the second element of this vector.
|
|
80 */
|
|
81 public A _2() {
|
|
82 return tail._1();
|
|
83 }
|
|
84
|
|
85 /**
|
|
86 * Returns the third element of this vector.
|
|
87 *
|
|
88 * @return the third element of this vector.
|
|
89 */
|
|
90 public A _3() {
|
|
91 return tail._2();
|
|
92 }
|
|
93
|
|
94 /**
|
|
95 * Returns the fourth element of this vector.
|
|
96 *
|
|
97 * @return the fourth element of this vector.
|
|
98 */
|
|
99 public A _4() {
|
|
100 return tail._3();
|
|
101 }
|
|
102
|
|
103 /**
|
|
104 * Returns all but the first element of this vector, as a vector-3.
|
|
105 *
|
|
106 * @return all but the first element of this vector, as a vector-3.
|
|
107 */
|
|
108 public V3<A> tail() {
|
|
109 return tail;
|
|
110 }
|
|
111
|
|
112 /**
|
|
113 * Returns the first element of this vector, as a product-1.
|
|
114 *
|
|
115 * @return the first element of this vector, as a product-1.
|
|
116 */
|
|
117 public P1<A> head() {
|
|
118 return head;
|
|
119 }
|
|
120
|
|
121 /**
|
|
122 * Returns an iterator for the elements of this vector.
|
|
123 *
|
|
124 * @return an iterator for the elements of this vector.
|
|
125 */
|
|
126 public Iterator<A> iterator() {
|
|
127 return toStream().iterator();
|
|
128 }
|
|
129
|
|
130 /**
|
|
131 * Returns a homogeneous product-4 equivalent to this vector.
|
|
132 *
|
|
133 * @return a homogeneous product-4 equivalent to this vector.
|
|
134 */
|
|
135 public P4<A, A, A, A> p() {
|
|
136 return new P4<A, A, A, A>() {
|
|
137 public A _1() {
|
|
138 return V4.this._1();
|
|
139 }
|
|
140
|
|
141 public A _2() {
|
|
142 return V4.this._2();
|
|
143 }
|
|
144
|
|
145 public A _3() {
|
|
146 return V4.this._3();
|
|
147 }
|
|
148
|
|
149 public A _4() {
|
|
150 return V4.this._4();
|
|
151 }
|
|
152 };
|
|
153 }
|
|
154
|
|
155 /**
|
|
156 * Returns a nonempty list with the elements of this vector.
|
|
157 *
|
|
158 * @return a nonempty list with the elements of this vector.
|
|
159 */
|
|
160 public NonEmptyList<A> toNonEmptyList() {
|
|
161 return NonEmptyList.nel(_1(), tail.toNonEmptyList().toList());
|
|
162 }
|
|
163
|
|
164 /**
|
|
165 * Returns a stream of the elements of this vector.
|
|
166 *
|
|
167 * @return a stream of the elements of this vector.
|
|
168 */
|
|
169 public Stream<A> toStream() {
|
|
170 return Stream.cons(head._1(), new P1<Stream<A>>() {
|
|
171 public Stream<A> _1() {
|
|
172 return tail.toStream();
|
|
173 }
|
|
174 });
|
|
175 }
|
|
176
|
|
177 /**
|
|
178 * Returns an array with the elements of this vector.
|
|
179 *
|
|
180 * @return an array with the elements of this vector.
|
|
181 */
|
|
182 @SuppressWarnings("unchecked")
|
|
183 public Array<A> toArray() {
|
|
184 return Array.array(_1(), _2(), _3(), _4());
|
|
185 }
|
|
186
|
|
187 /**
|
|
188 * Maps the given function across this vector.
|
|
189 *
|
|
190 * @param f The function to map across this vector.
|
|
191 * @return A new vector after the given function has been applied to each element.
|
|
192 */
|
|
193 public <B> V4<B> map(final F<A, B> f) {
|
|
194 return new V4<B>(head.map(f), tail.map(f));
|
|
195 }
|
|
196
|
|
197 /**
|
|
198 * Performs function application within a vector (applicative functor pattern).
|
|
199 *
|
|
200 * @param vf The vector of functions to apply.
|
|
201 * @return A new vector after zipping the given vector of functions over this vector.
|
|
202 */
|
|
203 public <B> V4<B> apply(final V4<F<A, B>> vf) {
|
|
204 return new V4<B>(head.<B>apply(vf.head()), tail.apply(vf.tail()));
|
|
205 }
|
|
206
|
|
207 /**
|
|
208 * Zips this vector with the given vector using the given function to produce a new vector.
|
|
209 *
|
|
210 * @param bs The vector to zip this vector with.
|
|
211 * @param f The function to zip this vector and the given vector with.
|
|
212 * @return A new vector with the results of the function.
|
|
213 */
|
|
214 public <B, C> V4<C> zipWith(final F<A, F<B, C>> f, final V4<B> bs) {
|
|
215 return bs.apply(map(f));
|
|
216 }
|
|
217
|
|
218 /**
|
|
219 * Zips this vector with the given vector to produce a vector of pairs.
|
|
220 *
|
|
221 * @param bs The vector to zip this vector with.
|
|
222 * @return A new vector with a length the same as the shortest of this vector and the given
|
|
223 * vector.
|
|
224 */
|
|
225 public <B> V4<P2<A, B>> zip(final V4<B> bs) {
|
|
226 final F<A, F<B, P2<A, B>>> __2 = p2();
|
|
227 return zipWith(__2, bs);
|
|
228 }
|
|
229
|
|
230 /**
|
|
231 * Zips this vector with the given vector to produce a vector of vectors.
|
|
232 *
|
|
233 * @param bs The vector to zip this vector with.
|
|
234 * @return A new vector of vectors.
|
|
235 */
|
|
236 public V4<V2<A>> vzip(final V4<A> bs) {
|
|
237 final F2<A, A, V2<A>> __2 = V.v2();
|
|
238 return zipWith(curry(__2), bs);
|
|
239 }
|
|
240
|
|
241 /**
|
|
242 * Returns a function that transforms a vector-4 to a stream of its elements.
|
|
243 *
|
|
244 * @return a function that transforms a vector-4 to a stream of its elements.
|
|
245 */
|
|
246 public static <A> F<V4<A>, Stream<A>> toStream_() {
|
|
247 return new F<V4<A>, Stream<A>>() {
|
|
248 public Stream<A> f(final V4<A> v) {
|
|
249 return v.toStream();
|
|
250 }
|
|
251 };
|
|
252 }
|
|
253
|
|
254 /**
|
|
255 * Returns a function that transforms a vector-4 to the equivalent product-4.
|
|
256 *
|
|
257 * @return a function that transforms a vector-4 to the equivalent product-4.
|
|
258 */
|
|
259 public static <A> F<V4<A>, P4<A, A, A, A>> p_() {
|
|
260 return new F<V4<A>, P4<A, A, A, A>>() {
|
|
261 public P4<A, A, A, A> f(final V4<A> v) {
|
|
262 return v.p();
|
|
263 }
|
|
264 };
|
|
265 }
|
|
266
|
|
267 /**
|
|
268 * A first-class function to get the first element of a vector.
|
|
269 *
|
|
270 * @return a function that gets the first element of a given vector.
|
|
271 */
|
|
272 public static <A> F<V4<A>, A> __1() {
|
|
273 return new F<V4<A>, A>() {
|
|
274 public A f(final V4<A> v) {
|
|
275 return v._1();
|
|
276 }
|
|
277 };
|
|
278 }
|
|
279
|
|
280 /**
|
|
281 * A first-class function to get the second element of a vector.
|
|
282 *
|
|
283 * @return a function that gets the second element of a given vector.
|
|
284 */
|
|
285 public static <A> F<V4<A>, A> __2() {
|
|
286 return new F<V4<A>, A>() {
|
|
287 public A f(final V4<A> v) {
|
|
288 return v._2();
|
|
289 }
|
|
290 };
|
|
291 }
|
|
292
|
|
293 /**
|
|
294 * A first-class function to get the third element of a vector.
|
|
295 *
|
|
296 * @return a function that gets the third element of a given vector.
|
|
297 */
|
|
298 public static <A> F<V4<A>, A> __3() {
|
|
299 return new F<V4<A>, A>() {
|
|
300 public A f(final V4<A> v) {
|
|
301 return v._3();
|
|
302 }
|
|
303 };
|
|
304 }
|
|
305
|
|
306 /**
|
|
307 * A first-class function to get the fourth element of a vector.
|
|
308 *
|
|
309 * @return a function that gets the fourth element of a given vector.
|
|
310 */
|
|
311 public static <A> F<V4<A>, A> __4() {
|
|
312 return new F<V4<A>, A>() {
|
|
313 public A f(final V4<A> v) {
|
|
314 return v._4();
|
|
315 }
|
|
316 };
|
|
317 }
|
|
318 }
|