001 package fj.data.vector; 002 003 import fj.F; 004 import fj.F2; 005 import fj.P1; 006 import fj.P2; 007 import fj.P6; 008 import fj.P7; 009 import static fj.Function.curry; 010 import static fj.P.p2; 011 import fj.data.Array; 012 import fj.data.NonEmptyList; 013 import fj.data.Stream; 014 015 import java.util.Iterator; 016 017 /** 018 * A vector-7. 019 */ 020 public final class V7<A> implements Iterable<A> { 021 022 private final V6<A> tail; 023 private final P1<A> head; 024 025 private V7(final P1<A> head, final V6<A> tail) { 026 this.head = head; 027 this.tail = tail; 028 } 029 030 /** 031 * Creates a vector-7 from a homogeneous product-7. 032 * 033 * @param p The product-7 from which to create a vector. 034 * @return A new vector-7. 035 */ 036 public static <A> V7<A> p(final P7<A, A, A, A, A, A, A> p) { 037 return new V7<A>(new P1<A>() { 038 public A _1() { 039 return p._1(); 040 } 041 }, V6.p(new P6<A, A, A, A, A, A>() { 042 public A _1() { 043 return p._2(); 044 } 045 046 public A _2() { 047 return p._3(); 048 } 049 050 public A _3() { 051 return p._4(); 052 } 053 054 public A _4() { 055 return p._5(); 056 } 057 058 public A _5() { 059 return p._6(); 060 } 061 062 public A _6() { 063 return p._7(); 064 } 065 })); 066 } 067 068 /** 069 * Creates a vector-7 from a head and a tail. 070 * 071 * @param head The value to put as the first element of the vector. 072 * @param tail The vector representing all but the first element of the new vector. 073 * @return The new vector. 074 */ 075 public static <A> V7<A> cons(final P1<A> head, final V6<A> tail) { 076 return new V7<A>(head, tail); 077 } 078 079 /** 080 * Returns the first element of this vector. 081 * 082 * @return the first element of this vector. 083 */ 084 public A _1() { 085 return head._1(); 086 } 087 088 /** 089 * Returns the second element of this vector. 090 * 091 * @return the second element of this vector. 092 */ 093 public A _2() { 094 return tail._1(); 095 } 096 097 /** 098 * Returns the third element of this vector. 099 * 100 * @return the third element of this vector. 101 */ 102 public A _3() { 103 return tail._2(); 104 } 105 106 /** 107 * Returns the fourth element of this vector. 108 * 109 * @return the fourth element of this vector. 110 */ 111 public A _4() { 112 return tail._3(); 113 } 114 115 /** 116 * Returns the fifth element of this vector. 117 * 118 * @return the fifth element of this vector. 119 */ 120 public A _5() { 121 return tail._4(); 122 } 123 124 /** 125 * Returns the sixth element of this vector. 126 * 127 * @return the sixth element of this vector. 128 */ 129 public A _6() { 130 return tail._5(); 131 } 132 133 /** 134 * Returns the seventh element of this vector. 135 * 136 * @return the seventh element of this vector. 137 */ 138 public A _7() { 139 return tail._6(); 140 } 141 142 /** 143 * Returns all but the first element of this vector, as a vector-6. 144 * 145 * @return all but the first element of this vector, as a vector-6. 146 */ 147 public V6<A> tail() { 148 return tail; 149 } 150 151 /** 152 * Returns the first element of this vector, as a product-1. 153 * 154 * @return the first element of this vector, as a product-1. 155 */ 156 public P1<A> head() { 157 return head; 158 } 159 160 /** 161 * Returns an iterator for the elements of this vector. 162 * 163 * @return an iterator for the elements of this vector. 164 */ 165 public Iterator<A> iterator() { 166 return toStream().iterator(); 167 } 168 169 /** 170 * Returns a homogeneous product-7 equivalent to this vector. 171 * 172 * @return a homogeneous product-7 equivalent to this vector. 173 */ 174 public P7<A, A, A, A, A, A, A> p() { 175 return new P7<A, A, A, A, A, A, A>() { 176 public A _1() { 177 return V7.this._1(); 178 } 179 180 public A _2() { 181 return V7.this._2(); 182 } 183 184 public A _3() { 185 return V7.this._3(); 186 } 187 188 public A _4() { 189 return V7.this._4(); 190 } 191 192 public A _5() { 193 return V7.this._5(); 194 } 195 196 public A _6() { 197 return V7.this._6(); 198 } 199 200 public A _7() { 201 return V7.this._7(); 202 } 203 }; 204 } 205 206 /** 207 * Returns a nonempty list with the elements of this vector. 208 * 209 * @return a nonempty list with the elements of this vector. 210 */ 211 public NonEmptyList<A> toNonEmptyList() { 212 return NonEmptyList.nel(_1(), tail.toNonEmptyList().toList()); 213 } 214 215 /** 216 * Returns a stream of the elements of this vector. 217 * 218 * @return a stream of the elements of this vector. 219 */ 220 public Stream<A> toStream() { 221 return Stream.cons(head._1(), new P1<Stream<A>>() { 222 public Stream<A> _1() { 223 return tail.toStream(); 224 } 225 }); 226 } 227 228 /** 229 * Returns an array with the elements of this vector. 230 * 231 * @return an array with the elements of this vector. 232 */ 233 @SuppressWarnings("unchecked") 234 public Array<A> toArray() { 235 return Array.array(_1(), _2(), _3(), _4(), _5(), _6(), _7()); 236 } 237 238 /** 239 * Maps the given function across this vector. 240 * 241 * @param f The function to map across this vector. 242 * @return A new vector after the given function has been applied to each element. 243 */ 244 public <B> V7<B> map(final F<A, B> f) { 245 return new V7<B>(head.map(f), tail.map(f)); 246 } 247 248 /** 249 * Performs function application within a vector (applicative functor pattern). 250 * 251 * @param vf The vector of functions to apply. 252 * @return A new vector after zipping the given vector of functions over this vector. 253 */ 254 public <B> V7<B> apply(final V7<F<A, B>> vf) { 255 return new V7<B>(P1.<A, B>apply(head, vf.head()), tail.apply(vf.tail())); 256 } 257 258 /** 259 * Zips this vector with the given vector using the given function to produce a new vector. 260 * 261 * @param bs The vector to zip this vector with. 262 * @param f The function to zip this vector and the given vector with. 263 * @return A new vector with the results of the function. 264 */ 265 public <B, C> V7<C> zipWith(final F<A, F<B, C>> f, final V7<B> bs) { 266 return bs.apply(map(f)); 267 } 268 269 /** 270 * Zips this vector with the given vector to produce a vector of pairs. 271 * 272 * @param bs The vector to zip this vector with. 273 * @return A new vector with a length the same as the shortest of this vector and the given 274 * vector. 275 */ 276 public <B> V7<P2<A, B>> zip(final V7<B> bs) { 277 final F<A, F<B, P2<A, B>>> __2 = p2(); 278 return zipWith(__2, bs); 279 } 280 281 /** 282 * Zips this vector with the given vector to produce a vector of vectors. 283 * 284 * @param bs The vector to zip this vector with. 285 * @return A new vector of vectors. 286 */ 287 public V7<V2<A>> vzip(final V7<A> bs) { 288 final F2<A, A, V2<A>> __2 = V.v2(); 289 return zipWith(curry(__2), bs); 290 } 291 292 /** 293 * Returns a function that transforms a vector-7 to a stream of its elements. 294 * 295 * @return a function that transforms a vector-7 to a stream of its elements. 296 */ 297 public static <A> F<V7<A>, Stream<A>> toStream_() { 298 return new F<V7<A>, Stream<A>>() { 299 public Stream<A> f(final V7<A> v) { 300 return v.toStream(); 301 } 302 }; 303 } 304 305 /** 306 * Returns a function that transforms a vector-7 to the equivalent product-7. 307 * 308 * @return a function that transforms a vector-7 to the equivalent product-7. 309 */ 310 public static <A> F<V7<A>, P7<A, A, A, A, A, A, A>> p_() { 311 return new F<V7<A>, P7<A, A, A, A, A, A, A>>() { 312 public P7<A, A, A, A, A, A, A> f(final V7<A> v) { 313 return v.p(); 314 } 315 }; 316 } 317 318 /** 319 * A first-class function to get the first element of a vector. 320 * 321 * @return a function that gets the first element of a given vector. 322 */ 323 public static <A> F<V7<A>, A> __1() { 324 return new F<V7<A>, A>() { 325 public A f(final V7<A> v) { 326 return v._1(); 327 } 328 }; 329 } 330 331 /** 332 * A first-class function to get the second element of a vector. 333 * 334 * @return a function that gets the second element of a given vector. 335 */ 336 public static <A> F<V7<A>, A> __2() { 337 return new F<V7<A>, A>() { 338 public A f(final V7<A> v) { 339 return v._2(); 340 } 341 }; 342 } 343 344 /** 345 * A first-class function to get the third element of a vector. 346 * 347 * @return a function that gets the third element of a given vector. 348 */ 349 public static <A> F<V7<A>, A> __3() { 350 return new F<V7<A>, A>() { 351 public A f(final V7<A> v) { 352 return v._3(); 353 } 354 }; 355 } 356 357 /** 358 * A first-class function to get the third element of a vector. 359 * 360 * @return a function that gets the third element of a given vector. 361 */ 362 public static <A> F<V7<A>, A> __4() { 363 return new F<V7<A>, A>() { 364 public A f(final V7<A> v) { 365 return v._4(); 366 } 367 }; 368 } 369 370 /** 371 * A first-class function to get the third element of a vector. 372 * 373 * @return a function that gets the third element of a given vector. 374 */ 375 public static <A> F<V7<A>, A> __5() { 376 return new F<V7<A>, A>() { 377 public A f(final V7<A> v) { 378 return v._5(); 379 } 380 }; 381 } 382 383 /** 384 * A first-class function to get the third element of a vector. 385 * 386 * @return a function that gets the third element of a given vector. 387 */ 388 public static <A> F<V7<A>, A> __6() { 389 return new F<V7<A>, A>() { 390 public A f(final V7<A> v) { 391 return v._6(); 392 } 393 }; 394 } 395 396 /** 397 * A first-class function to get the third element of a vector. 398 * 399 * @return a function that gets the third element of a given vector. 400 */ 401 public static <A> F<V7<A>, A> __7() { 402 return new F<V7<A>, A>() { 403 public A f(final V7<A> v) { 404 return v._7(); 405 } 406 }; 407 } 408 409 }