0
|
1 package fj.data.vector;
|
|
2
|
|
3 import fj.F;
|
|
4 import fj.F2;
|
|
5 import static fj.Function.curry;
|
|
6 import static fj.P.p2;
|
|
7 import fj.P1;
|
|
8 import fj.P2;
|
|
9 import fj.data.Array;
|
|
10 import fj.data.List;
|
|
11 import fj.data.NonEmptyList;
|
|
12 import fj.data.Stream;
|
|
13
|
|
14 import java.util.Iterator;
|
|
15
|
|
16 /**
|
|
17 * A vector-2.
|
|
18 */
|
|
19 public final class V2<A> implements Iterable<A> {
|
|
20
|
|
21 private final P2<A, A> inner;
|
|
22
|
|
23 private V2(final P2<A, A> inner) {
|
|
24 this.inner = inner;
|
|
25 }
|
|
26
|
|
27 /**
|
|
28 * Creates a vector-2 from a homogeneous product-2.
|
|
29 *
|
|
30 * @param p The product-2 from which to create a vector.
|
|
31 * @return A new vector-2.
|
|
32 */
|
|
33 public static <A> V2<A> p(final P2<A, A> p) {
|
|
34 return new V2<A>(p);
|
|
35 }
|
|
36
|
|
37 /**
|
|
38 * Returns the first element of this vector.
|
|
39 *
|
|
40 * @return the first element of this vector.
|
|
41 */
|
|
42 public A _1() {
|
|
43 return inner._1();
|
|
44 }
|
|
45
|
|
46 /**
|
|
47 * Returns the second element of this vector.
|
|
48 *
|
|
49 * @return the second element of this vector.
|
|
50 */
|
|
51 public A _2() {
|
|
52 return inner._2();
|
|
53 }
|
|
54
|
|
55 /**
|
|
56 * A first-class function to get the first element of a vector.
|
|
57 *
|
|
58 * @return a function that gets the first element of a given vector.
|
|
59 */
|
|
60 public static <A> F<V2<A>, A> __1() {
|
|
61 return new F<V2<A>, A>() {
|
|
62 public A f(final V2<A> v) {
|
|
63 return v._1();
|
|
64 }
|
|
65 };
|
|
66 }
|
|
67
|
|
68 /**
|
|
69 * A first-class function to get the second element of a vector.
|
|
70 *
|
|
71 * @return a function that gets the second element of a given vector.
|
|
72 */
|
|
73 public static <A> F<V2<A>, A> __2() {
|
|
74 return new F<V2<A>, A>() {
|
|
75 public A f(final V2<A> v) {
|
|
76 return v._2();
|
|
77 }
|
|
78 };
|
|
79 }
|
|
80
|
|
81 /**
|
|
82 * Returns an iterator for the elements of this vector.
|
|
83 *
|
|
84 * @return an iterator for the elements of this vector.
|
|
85 */
|
|
86 public Iterator<A> iterator() {
|
|
87 return toStream().iterator();
|
|
88 }
|
|
89
|
|
90 /**
|
|
91 * Returns a homogeneous product-2 equivalent to this vector.
|
|
92 *
|
|
93 * @return a homogeneous product-2 equivalent to this vector.
|
|
94 */
|
|
95 public P2<A, A> p() {
|
|
96 return inner;
|
|
97 }
|
|
98
|
|
99 /**
|
|
100 * Returns a nonempty list with the elements of this vector.
|
|
101 *
|
|
102 * @return a nonempty list with the elements of this vector.
|
|
103 */
|
|
104 public NonEmptyList<A> toNonEmptyList() {
|
|
105 return NonEmptyList.nel(_1(), List.single(_2()));
|
|
106 }
|
|
107
|
|
108 /**
|
|
109 * Returns a stream of the elements of this vector.
|
|
110 *
|
|
111 * @return a stream of the elements of this vector.
|
|
112 */
|
|
113 public Stream<A> toStream() {
|
|
114 return Stream.cons(_1(), new P1<Stream<A>>() {
|
|
115 public Stream<A> _1() {
|
|
116 return Stream.single(_2());
|
|
117 }
|
|
118 });
|
|
119 }
|
|
120
|
|
121 /**
|
|
122 * Returns a function that transforms a vector-2 to a stream of its elements.
|
|
123 *
|
|
124 * @return a function that transforms a vector-2 to a stream of its elements.
|
|
125 */
|
|
126 public static <A> F<V2<A>, Stream<A>> toStream_() {
|
|
127 return new F<V2<A>, Stream<A>>() {
|
|
128 public Stream<A> f(final V2<A> v) {
|
|
129 return v.toStream();
|
|
130 }
|
|
131 };
|
|
132 }
|
|
133
|
|
134 /**
|
|
135 * Returns a function that transforms a vector-2 to the equivalent product-2.
|
|
136 *
|
|
137 * @return a function that transforms a vector-2 to the equivalent product-2.
|
|
138 */
|
|
139 public static <A> F<V2<A>, P2<A, A>> p_() {
|
|
140 return new F<V2<A>, P2<A, A>>() {
|
|
141 public P2<A, A> f(final V2<A> v) {
|
|
142 return v.p();
|
|
143 }
|
|
144 };
|
|
145 }
|
|
146
|
|
147 /**
|
|
148 * Returns an array with the elements of this vector.
|
|
149 *
|
|
150 * @return an array with the elements of this vector.
|
|
151 */
|
|
152 @SuppressWarnings("unchecked")
|
|
153 public Array<A> toArray() {
|
|
154 return Array.array(_1(), _2());
|
|
155 }
|
|
156
|
|
157 /**
|
|
158 * Maps the given function across this vector.
|
|
159 *
|
|
160 * @param f The function to map across this vector.
|
|
161 * @return A new vector after the given function has been applied to each element.
|
|
162 */
|
|
163 public <B> V2<B> map(final F<A, B> f) {
|
|
164 return p(inner.split(f, f));
|
|
165 }
|
|
166
|
|
167 /**
|
|
168 * Performs function application within a vector (applicative functor pattern).
|
|
169 *
|
|
170 * @param vf The vector of functions to apply.
|
|
171 * @return A new vector after zipping the given vector of functions over this vector.
|
|
172 */
|
|
173 public <B> V2<B> apply(final V2<F<A, B>> vf) {
|
|
174 return p(inner.split(vf._1(), vf._2()));
|
|
175 }
|
|
176
|
|
177 /**
|
|
178 * Zips this vector with the given vector using the given function to produce a new vector.
|
|
179 *
|
|
180 * @param bs The vector to zip this vector with.
|
|
181 * @param f The function to zip this vector and the given vector with.
|
|
182 * @return A new vector with the results of the function.
|
|
183 */
|
|
184 public <B, C> V2<C> zipWith(final F<A, F<B, C>> f, final V2<B> bs) {
|
|
185 return bs.apply(map(f));
|
|
186 }
|
|
187
|
|
188 /**
|
|
189 * Zips this vector with the given vector to produce a vector of pairs.
|
|
190 *
|
|
191 * @param bs The vector to zip this vector with.
|
|
192 * @return A new vector with a length the same as the shortest of this vector and the given
|
|
193 * vector.
|
|
194 */
|
|
195 public <B> V2<P2<A, B>> zip(final V2<B> bs) {
|
|
196 final F<A, F<B, P2<A, B>>> __2 = p2();
|
|
197 return zipWith(__2, bs);
|
|
198 }
|
|
199
|
|
200 /**
|
|
201 * Zips this vector with the given vector to produce a vector of vectors.
|
|
202 *
|
|
203 * @param bs The vector to zip this vector with.
|
|
204 * @return A new vector of vectors.
|
|
205 */
|
|
206 public V2<V2<A>> vzip(final V2<A> bs) {
|
|
207 final F2<A, A, V2<A>> __2 = V.v2();
|
|
208 return zipWith(curry(__2), bs);
|
|
209 }
|
|
210
|
|
211 /**
|
|
212 * Return the first element of this vector as a product-1.
|
|
213 *
|
|
214 * @return the first element of this vector as a product-1.
|
|
215 */
|
|
216 public P1<A> head() {
|
|
217 return new P1<A>() {
|
|
218 public A _1() {
|
|
219 return V2.this._1();
|
|
220 }
|
|
221 };
|
|
222 }
|
|
223
|
|
224 }
|