All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fj.data.vector.V8 Maven / Gradle / Ivy

Go to download

Functional Java is an open source library that supports closures for the Java programming language

There is a newer version: 5.0
Show newest version
package fj.data.vector;

import fj.F;
import fj.F2;
import fj.P1;
import fj.P2;
import fj.P7;
import fj.P8;
import static fj.Function.curry;
import static fj.P.p2;
import fj.data.Array;
import fj.data.NonEmptyList;
import fj.data.Stream;

import java.util.Iterator;

/**
 * A vector-8.
 */
public final class V8 implements Iterable {

  private final V7 tail;
  private final P1 head;

  private V8(final P1 head, final V7 tail) {
    this.head = head;
    this.tail = tail;
  }

  /**
   * Creates a vector-8 from a homogeneous product-8.
   *
   * @param p The product-8 from which to create a vector.
   * @return A new vector-8.
   */
  public static  V8 p(final P8 p) {
    return new V8(new P1() {
      public A _1() {
        return p._1();
      }
    }, V7.p(new P7() {
      public A _1() {
        return p._2();
      }

      public A _2() {
        return p._3();
      }

      public A _3() {
        return p._4();
      }

      public A _4() {
        return p._5();
      }

      public A _5() {
        return p._6();
      }

      public A _6() {
        return p._7();
      }

      public A _7() {
        return p._8();
      }
    }));
  }

  /**
   * Creates a vector-8 from a head and a tail.
   *
   * @param head The value to put as the first element of the vector.
   * @param tail The vector representing all but the first element of the new vector.
   * @return The new vector.
   */
  public static  V8 cons(final P1 head, final V7 tail) {
    return new V8(head, tail);
  }

  /**
   * Returns the first element of this vector.
   *
   * @return the first element of this vector.
   */
  public A _1() {
    return head._1();
  }

  /**
   * Returns the second element of this vector.
   *
   * @return the second element of this vector.
   */
  public A _2() {
    return tail._1();
  }

  /**
   * Returns the third element of this vector.
   *
   * @return the third element of this vector.
   */
  public A _3() {
    return tail._2();
  }

  /**
   * Returns the fourth element of this vector.
   *
   * @return the fourth element of this vector.
   */
  public A _4() {
    return tail._3();
  }

  /**
   * Returns the fifth element of this vector.
   *
   * @return the fifth element of this vector.
   */
  public A _5() {
    return tail._4();
  }

  /**
   * Returns the sixth element of this vector.
   *
   * @return the sixth element of this vector.
   */
  public A _6() {
    return tail._5();
  }

  /**
   * Returns the seventh element of this vector.
   *
   * @return the seventh element of this vector.
   */
  public A _7() {
    return tail._6();
  }

  /**
   * Returns the eighth element of this vector.
   *
   * @return the eighth element of this vector.
   */
  public A _8() {
    return tail._7();
  }

  /**
   * Returns all but the first element of this vector, as a vector-7.
   *
   * @return all but the first element of this vector, as a vector-7.
   */
  public V7 tail() {
    return tail;
  }

  /**
   * Returns the first element of this vector, as a product-1.
   *
   * @return the first element of this vector, as a product-1.
   */
  public P1 head() {
    return head;
  }

  /**
   * Returns an iterator for the elements of this vector.
   *
   * @return an iterator for the elements of this vector.
   */
  public Iterator iterator() {
    return toStream().iterator();
  }

  /**
   * Returns a homogeneous product-8 equivalent to this vector.
   *
   * @return a homogeneous product-8 equivalent to this vector.
   */
  public P8 p() {
    return new P8() {
      public A _1() {
        return V8.this._1();
      }

      public A _2() {
        return V8.this._2();
      }

      public A _3() {
        return V8.this._3();
      }

      public A _4() {
        return V8.this._4();
      }

      public A _5() {
        return V8.this._5();
      }

      public A _6() {
        return V8.this._6();
      }

      public A _7() {
        return V8.this._7();
      }

      public A _8() {
        return V8.this._8();
      }
    };
  }

  /**
   * Returns a nonempty list with the elements of this vector.
   *
   * @return a nonempty list with the elements of this vector.
   */
  public NonEmptyList toNonEmptyList() {
    return NonEmptyList.nel(_1(), tail.toNonEmptyList().toList());
  }

  /**
   * Returns a stream of the elements of this vector.
   *
   * @return a stream of the elements of this vector.
   */
  public Stream toStream() {
    return Stream.cons(head._1(), new P1>() {
      public Stream _1() {
        return tail.toStream();
      }
    });
  }

  /**
   * Returns an array with the elements of this vector.
   *
   * @return an array with the elements of this vector.
   */
  @SuppressWarnings("unchecked")
  public Array toArray() {
    return Array.array(_1(), _2(), _3(), _4(), _5(), _6(), _7(), _8());
  }

  /**
   * Maps the given function across this vector.
   *
   * @param f The function to map across this vector.
   * @return A new vector after the given function has been applied to each element.
   */
  public  V8 map(final F f) {
    return new V8(head.map(f), tail.map(f));
  }

  /**
   * Performs function application within a vector (applicative functor pattern).
   *
   * @param vf The vector of functions to apply.
   * @return A new vector after zipping the given vector of functions over this vector.
   */
  public  V8 apply(final V8> vf) {
    return new V8(head.apply(vf.head()), tail.apply(vf.tail()));
  }

  /**
   * Zips this vector with the given vector using the given function to produce a new vector.
   *
   * @param bs The vector to zip this vector with.
   * @param f  The function to zip this vector and the given vector with.
   * @return A new vector with the results of the function.
   */
  public  V8 zipWith(final F> f, final V8 bs) {
    return bs.apply(map(f));
  }

  /**
   * Zips this vector with the given vector to produce a vector of pairs.
   *
   * @param bs The vector to zip this vector with.
   * @return A new vector with a length the same as the shortest of this vector and the given
   *         vector.
   */
  public  V8> zip(final V8 bs) {
    final F>> __2 = p2();
    return zipWith(__2, bs);
  }

  /**
   * Zips this vector with the given vector to produce a vector of vectors.
   *
   * @param bs The vector to zip this vector with.
   * @return A new vector of vectors.
   */
  public V8> vzip(final V8 bs) {
    final F2> __2 = V.v2();
    return zipWith(curry(__2), bs);
  }

  /**
   * Returns a function that transforms a vector-8 to a stream of its elements.
   *
   * @return a function that transforms a vector-8 to a stream of its elements.
   */
  public static  F, Stream> toStream_() {
    return new F, Stream>() {
      public Stream f(final V8 v) {
        return v.toStream();
      }
    };
  }

  /**
   * Returns a function that transforms a vector-8 to the equivalent product-8.
   *
   * @return a function that transforms a vector-8 to the equivalent product-8.
   */
  public static  F, P8> p_() {
    return new F, P8>() {
      public P8 f(final V8 v) {
        return v.p();
      }
    };
  }


  /**
   * A first-class function to get the first element of a vector.
   *
   * @return a function that gets the first element of a given vector.
   */
  public static  F, A> __1() {
    return new F, A>() {
      public A f(final V8 v) {
        return v._1();
      }
    };
  }

  /**
   * A first-class function to get the second element of a vector.
   *
   * @return a function that gets the second element of a given vector.
   */
  public static  F, A> __2() {
    return new F, A>() {
      public A f(final V8 v) {
        return v._2();
      }
    };
  }

  /**
   * A first-class function to get the third element of a vector.
   *
   * @return a function that gets the third element of a given vector.
   */
  public static  F, A> __3() {
    return new F, A>() {
      public A f(final V8 v) {
        return v._3();
      }
    };
  }

  /**
   * A first-class function to get the fourth element of a vector.
   *
   * @return a function that gets the fourth element of a given vector.
   */
  public static  F, A> __4() {
    return new F, A>() {
      public A f(final V8 v) {
        return v._4();
      }
    };
  }

  /**
   * A first-class function to get the fifth element of a vector.
   *
   * @return a function that gets the fifth element of a given vector.
   */
  public static  F, A> __5() {
    return new F, A>() {
      public A f(final V8 v) {
        return v._5();
      }
    };
  }

  /**
   * A first-class function to get the sixth element of a vector.
   *
   * @return a function that gets the sixth element of a given vector.
   */
  public static  F, A> __6() {
    return new F, A>() {
      public A f(final V8 v) {
        return v._6();
      }
    };
  }

  /**
   * A first-class function to get the seventh element of a vector.
   *
   * @return a function that gets the seventh element of a given vector.
   */
  public static  F, A> __7() {
    return new F, A>() {
      public A f(final V8 v) {
        return v._7();
      }
    };
  }

  /**
   * A first-class function to get the eighth element of a vector.
   *
   * @return a function that gets the eighth element of a given vector.
   */
  public static  F, A> __8() {
    return new F, A>() {
      public A f(final V8 v) {
        return v._8();
      }
    };
  }

}