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

fj.data.fingertrees.Node3 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.fingertrees;

import fj.P;
import fj.P3;
import fj.data.Option;
import fj.data.vector.V3;
import fj.F;
import fj.P2;

import static fj.data.Option.none;
import static fj.data.Option.some;
import static fj.data.fingertrees.FingerTree.mkTree;

/**
 * A three-element inner tree node.
 */
public final class Node3 extends Node {
  private final V3 as;

  Node3(final Measured m, final V3 as) {
    super(m, m.sum(m.measure(as._1()), m.sum(m.measure(as._2()), m.measure(as._3()))));
    this.as = as;
  }

  public  B foldRight(final F> aff, final B z) {
    return aff.f(as._1()).f(aff.f(as._2()).f(aff.f(as._3()).f(z)));
  }

  public  B foldLeft(final F> bff, final B z) {
    return bff.f(bff.f(bff.f(z).f(as._1())).f(as._2())).f(as._3());
  }

  public  B match(final F, B> n2, final F, B> n3) {
    return n3.f(this);
  }

  public Digit toDigit() {
    return new Three(measured(), as);
  }

  P3>, A, Option>> split1(final F predicate, final V acc) {
    final Measured m = measured();
    final MakeTree mk = mkTree(m);
    final V acc1 = m.sum(acc, m.measure().f(as._1()));
    if (predicate.f(acc1)) {
      return P.p(none(), as._1(), some(mk.two(as._2(), as._3())));
    } else if (predicate.f(m.sum(acc1, m.measure().f(as._2())))) {
      return P.p(some(mk.one(as._1())), as._2(), some(mk.one(as._3())));
    } else {
      return P.p(some(mk.two(as._1(), as._2())), as._3(), none());
    }
  }

  @Override public P2 lookup(final F o, final int i) {
    final F m = measured().measure();
    final int s1 = o.f(m.f(as._1()));
    if (i < s1) {
      return P.p(i, as._1());
    } else {
      final int s2 = s1 + o.f(m.f(as._2()));
      if (i < s2) {
        return P.p(i - s1, as._2());
      } else {
        return P.p(i - s2, as._3());
      }
    }
  }

  public V3 toVector() {
    return as;
  }
}