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