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

fj.data.vector.V2 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.*;

import static fj.Function.curry;
import static fj.P.p2;

import fj.data.Array;
import fj.data.List;
import fj.data.NonEmptyList;
import fj.data.Stream;

import java.util.Iterator;

/**
 * A vector-2.
 */
public final class V2 implements Iterable {

  private final P2 inner;

  private V2(final P2 inner) {
    this.inner = inner;
  }

  /**
   * Creates a vector-2 from a homogeneous product-2.
   *
   * @param p The product-2 from which to create a vector.
   * @return A new vector-2.
   */
  public static  V2 p(final P2 p) {
    return new V2<>(p);
  }

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

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

  /**
   * 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 V2::_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 V2::_2;
  }

  /**
   * 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-2 equivalent to this vector.
   *
   * @return a homogeneous product-2 equivalent to this vector.
   */
  public P2 p() {
    return inner;
  }

  /**
   * 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(), List.single(_2()));
  }

  /**
   * Returns a stream of the elements of this vector.
   *
   * @return a stream of the elements of this vector.
   */
  public Stream toStream() {
    return Stream.cons(_1(), () -> Stream.single(_2()));
  }

  /**
   * Returns a function that transforms a vector-2 to a stream of its elements.
   *
   * @return a function that transforms a vector-2 to a stream of its elements.
   */
  public static  F, Stream> toStream_() {
    return V2::toStream;
  }

  /**
   * Returns a function that transforms a vector-2 to the equivalent product-2.
   *
   * @return a function that transforms a vector-2 to the equivalent product-2.
   */
  public static  F, P2> p_() {
    return V2::p;
  }

  /**
   * 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());
  }

  /**
   * 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  V2 map(final F f) {
    return p(inner.split(f, 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  V2 apply(final V2> vf) {
    return p(inner.split(vf._1(), vf._2()));
  }

  /**
   * 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  V2 zipWith(final F> f, final V2 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  V2> zip(final V2 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 V2> vzip(final V2 bs) {
    final F2> __2 = V.v2();
    return zipWith(curry(__2), bs);
  }

  /**
   * Return 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 P.lazy(V2.this::_1);
  }

}