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