Mercurial > hg > Members > tatsuki > functionaljava-master > core
view src/main/java/fj/data/fingertrees/Deep.java @ 0:fe80c1edf1be
add getLoop
author | tatsuki |
---|---|
date | Fri, 20 Mar 2015 21:04:03 +0900 |
parents | |
children |
line wrap: on
line source
package fj.data.fingertrees; import fj.F; import fj.Function; import fj.P2; import fj.data.vector.V2; import fj.data.vector.V3; import fj.data.vector.V4; import static fj.data.List.list; import static fj.Function.flip; /** * A finger tree with 1-4-digits on the left and right, and a finger tree of 2-3-nodes in the middle. */ public final class Deep<V, A> extends FingerTree<V, A> { private final V v; private final Digit<V, A> prefix; private final FingerTree<V, Node<V, A>> middle; private final Digit<V, A> suffix; Deep(final Measured<V, A> m, final V v, final Digit<V, A> prefix, final FingerTree<V, Node<V, A>> middle, final Digit<V, A> suffix) { super(m); this.v = v; this.prefix = prefix; this.middle = middle; this.suffix = suffix; } /** * Returns the first few elements of this tree. * * @return the first few elements of this tree. */ public Digit<V, A> prefix() { return prefix; } /** * Returns a finger tree of the inner nodes of this tree. * * @return a finger tree of the inner nodes of this tree. */ public FingerTree<V, Node<V, A>> middle() { return middle; } /** * Returns the last few elements of this tree. * * @return the last few elements of this tree. */ public Digit<V, A> suffix() { return suffix; } @Override public <B> B foldRight(final F<A, F<B, B>> aff, final B z) { return prefix.foldRight(aff, middle.foldRight(flip(Node.<V, A, B>foldRight_(aff)), suffix.foldRight(aff, z))); } @Override public A reduceRight(final F<A, F<A, A>> aff) { return prefix.foldRight(aff, middle.foldRight(flip(Node.<V, A, A>foldRight_(aff)), suffix.reduceRight(aff))); } @Override public <B> B foldLeft(final F<B, F<A, B>> bff, final B z) { return suffix.foldLeft(bff, middle.foldLeft(Node.<V, A, B>foldLeft_(bff), prefix.foldLeft(bff, z))); } @Override public A reduceLeft(final F<A, F<A, A>> aff) { return suffix.foldLeft(aff, middle.foldLeft(Node.<V, A, A>foldLeft_(aff), prefix.reduceLeft(aff))); } @Override public <B> FingerTree<V, B> map(final F<A, B> abf, final Measured<V, B> m) { return new Deep<V, B>(m, v, prefix.map(abf, m), middle.map(Node.<V, A, B>liftM(abf, m), m.nodeMeasured()), suffix.map(abf, m)); } /** * Returns the sum of the measurements of this tree's elements, according to the monoid. * * @return the sum of the measurements of this tree's elements, according to the monoid. */ public V measure() { return v; } /** * Pattern matching on the tree. Matches the function on the Deep tree. */ @Override public <B> B match(final F<Empty<V, A>, B> empty, final F<Single<V, A>, B> single, final F<Deep<V, A>, B> deep) { return deep.f(this); } @Override public FingerTree<V, A> cons(final A a) { final Measured<V, A> m = measured(); final V measure = m.sum(m.measure(a), v); final MakeTree<V, A> mk = mkTree(m); return prefix.match(new F<One<V, A>, FingerTree<V, A>>() { public FingerTree<V, A> f(final One<V, A> one) { return new Deep<V, A>(m, measure, mk.two(a, one.value()), middle, suffix); } }, new F<Two<V, A>, FingerTree<V, A>>() { public FingerTree<V, A> f(final Two<V, A> two) { return new Deep<V, A>(m, measure, mk.three(a, two.values()._1(), two.values()._2()), middle, suffix); } }, new F<Three<V, A>, FingerTree<V, A>>() { public FingerTree<V, A> f(final Three<V, A> three) { return new Deep<V, A>(m, measure, mk.four(a, three.values()._1(), three.values()._2(), three.values()._3()), middle, suffix); } }, new F<Four<V, A>, FingerTree<V, A>>() { public FingerTree<V, A> f(final Four<V, A> four) { return new Deep<V, A>(m, measure, mk.two(a, four.values()._1()), middle.cons(mk.node3(four.values()._2(), four.values()._3(), four.values()._4())), suffix); } }); } public FingerTree<V, A> snoc(final A a) { final Measured<V, A> m = measured(); final V measure = m.sum(m.measure(a), v); final MakeTree<V, A> mk = mkTree(m); return suffix.match(new F<One<V, A>, FingerTree<V, A>>() { public FingerTree<V, A> f(final One<V, A> one) { return new Deep<V, A>(m, measure, prefix, middle, mk.two(one.value(), a)); } }, new F<Two<V, A>, FingerTree<V, A>>() { public FingerTree<V, A> f(final Two<V, A> two) { return new Deep<V, A>(m, measure, prefix, middle, mk.three(two.values()._1(), two.values()._2(), a)); } }, new F<Three<V, A>, FingerTree<V, A>>() { public FingerTree<V, A> f(final Three<V, A> three) { return new Deep<V, A>(m, measure, prefix, middle, mk.four(three.values()._1(), three.values()._2(), three.values()._3(), a)); } }, new F<Four<V, A>, FingerTree<V, A>>() { public FingerTree<V, A> f(final Four<V, A> four) { return new Deep<V, A>(m, measure, prefix, middle.snoc(mk.node3(four.values()._1(), four.values()._2(), four.values()._3())), mk.two(four.values()._4(), a)); } }); } @Override public FingerTree<V, A> append(final FingerTree<V, A> t) { final Measured<V, A> m = measured(); return t.match(Function.<Empty<V, A>, FingerTree<V, A>>constant(t), new F<Single<V, A>, FingerTree<V, A>>() { public FingerTree<V, A> f(final Single<V, A> single) { return t.snoc(single.value()); } }, new F<Deep<V, A>, FingerTree<V, A>>() { public FingerTree<V, A> f(final Deep<V, A> deep) { return new Deep<V, A>(m, m.sum(measure(), deep.measure()), prefix, addDigits0(m, middle, suffix, deep.prefix, deep.middle), deep.suffix); } }); } @SuppressWarnings({"ReturnOfNull", "IfStatementWithIdenticalBranches"}) @Override public P2<Integer, A> lookup(final F<V, Integer> o, final int i) { final int spr = o.f(prefix.measure()); final int spm = o.f(middle.measure()); if (i < spr) return null; // TODO //return prefix.lookup(o, i); if (i < spm) { return null; // TODO /* final P2<Integer, Node<V, A>> p = middle.lookup(o, i - spr); return p._2().lookup(o, p._1()); */ } return null; // TODO suffix.lookup(i - spm); } private static <V, A> FingerTree<V, Node<V, A>> addDigits0(final Measured<V, A> m, final FingerTree<V, Node<V, A>> m1, final Digit<V, A> s1, final Digit<V, A> p2, final FingerTree<V, Node<V, A>> m2) { final MakeTree<V, A> mk = mkTree(m); return s1.match(new F<One<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final One<V, A> one1) { return p2.match(new F<One<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final One<V, A> one2) { return append1(m, m1, mk.node2(one1.value(), one2.value()), m2); } }, new F<Two<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Two<V, A> two2) { final V2<A> vs = two2.values(); return append1(m, m1, mk.node3(one1.value(), vs._1(), vs._2()), m2); } }, new F<Three<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Three<V, A> three) { final V3<A> vs = three.values(); return append2(m, m1, mk.node2(one1.value(), vs._1()), mk.node2(vs._2(), vs._3()), m2); } }, new F<Four<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Four<V, A> four) { final V4<A> vs = four.values(); return append2(m, m1, mk.node3(one1.value(), vs._1(), vs._2()), mk.node2(vs._3(), vs._4()), m2); } }); } }, new F<Two<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Two<V, A> two1) { final V2<A> v1 = two1.values(); return p2.match(new F<One<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final One<V, A> one) { return append1(m, m1, mk.node3(v1._1(), v1._2(), one.value()), m2); } }, new F<Two<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Two<V, A> two2) { final V2<A> v2 = two2.values(); return append2(m, m1, mk.node2(v1._1(), v1._2()), mk.node2(v2._1(), v2._2()), m2); } }, new F<Three<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Three<V, A> three) { final V3<A> v2 = three.values(); return append2(m, m1, mk.node3(v1._1(), v1._2(), v2._1()), mk.node2(v2._2(), v2._3()), m2); } }, new F<Four<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Four<V, A> four) { final V4<A> v2 = four.values(); return append2(m, m1, mk.node3(v1._1(), v1._2(), v2._1()), mk.node3(v2._2(), v2._3(), v2._4()), m2); } }); } }, new F<Three<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Three<V, A> three1) { final V3<A> v1 = three1.values(); return p2.match(new F<One<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final One<V, A> one) { return append2(m, m1, mk.node2(v1._1(), v1._2()), mk.node2(v1._3(), one.value()), m2); } }, new F<Two<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Two<V, A> two) { final V2<A> v2 = two.values(); return append2(m, m1, mk.node3(v1), mk.node2(v2), m2); } }, new F<Three<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Three<V, A> three2) { return append2(m, m1, mk.node3(v1), mk.node3(three2.values()), m2); } }, new F<Four<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Four<V, A> four) { return append3(m, m1, mk.node3(v1), mk.node2(four.values()._1(), four.values()._2()), mk.node2(four.values()._3(), four.values()._4()), m2); } }); } }, new F<Four<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Four<V, A> four1) { final V4<A> v1 = four1.values(); return p2.match(new F<One<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final One<V, A> one) { return append2(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node2(v1._4(), one.value()), m2); } }, new F<Two<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Two<V, A> two) { final V2<A> v2 = two.values(); return append2(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), v2._1(), v2._2()), m2); } }, new F<Three<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Three<V, A> three) { final V3<A> v2 = three.values(); return append3(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node2(v1._4(), v2._1()), mk.node2(v2._2(), v2._3()), m2); } }, new F<Four<V, A>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Four<V, A> four2) { final V4<A> v2 = four2.values(); return append3(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), v2._1(), v2._2()), mk.node2(v2._3(), v2._4()), m2); } }); } }); } private static <V, A> FingerTree<V, Node<V, A>> append1(final Measured<V, A> m, final FingerTree<V, Node<V, A>> xs, final Node<V, A> a, final FingerTree<V, Node<V, A>> ys) { return xs.match(new F<Empty<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Empty<V, Node<V, A>> empty) { return ys.cons(a); } }, new F<Single<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Single<V, Node<V, A>> single) { return ys.cons(a).cons(single.value()); } }, new F<Deep<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Deep<V, Node<V, A>> deep1) { return ys.match(new F<Empty<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Empty<V, Node<V, A>> empty) { return xs.snoc(a); } }, new F<Single<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Single<V, Node<V, A>> single) { return xs.snoc(a).snoc(single.value()); } }, new F<Deep<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Deep<V, Node<V, A>> deep2) { final Measured<V, Node<V, A>> nm = m.nodeMeasured(); return new Deep<V, Node<V, A>>(nm, m.sum(m.sum(deep1.v, nm.measure(a)), deep2.v), deep1.prefix, addDigits1(nm, deep1.middle, deep1.suffix, a, deep2.prefix, deep2.middle), deep2.suffix); } }); } }); } private static <V, A> FingerTree<V, Node<V, Node<V, A>>> addDigits1(final Measured<V, Node<V, A>> m, final FingerTree<V, Node<V, Node<V, A>>> m1, final Digit<V, Node<V, A>> x, final Node<V, A> n, final Digit<V, Node<V, A>> y, final FingerTree<V, Node<V, Node<V, A>>> m2) { final MakeTree<V, Node<V, A>> mk = mkTree(m); return x.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one1) { return y.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one2) { return append1(m, m1, mk.node3(one1.value(), n, one2.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { return append2(m, m1, mk.node2(one1.value(), n), mk.node2(two.values()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { final V3<Node<V, A>> v2 = three.values(); return append2(m, m1, mk.node3(one1.value(), n, v2._1()), mk.node2(v2._2(), v2._3()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v2 = four.values(); return append2(m, m1, mk.node3(one1.value(), n, v2._1()), mk.node3(v2._2(), v2._3(), v2._4()), m2); } }); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two1) { final V2<Node<V, A>> v1 = two1.values(); return y.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one) { return append2(m, m1, mk.node2(v1), mk.node2(n, one.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { return append2(m, m1, mk.node3(v1._1(), v1._2(), n), mk.node2(two.values()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { return append2(m, m1, mk.node3(v1._1(), v1._2(), n), mk.node3(three.values()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v2 = four.values(); return append3(m, m1, mk.node3(v1._1(), v1._2(), n), mk.node2(v2._1(), v2._2()), mk.node2(v2._3(), v2._4()), m2); } }); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { final V3<Node<V, A>> v1 = three.values(); return y.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one) { return append2(m, m1, mk.node3(v1), mk.node2(n, one.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { final V2<Node<V, A>> v2 = two.values(); return append2(m, m1, mk.node3(v1), mk.node3(n, v2._1(), v2._2()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { final V3<Node<V, A>> v2 = three.values(); return append3(m, m1, mk.node3(v1), mk.node2(n, v2._1()), mk.node2(v2._2(), v2._3()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v2 = four.values(); return append3(m, m1, mk.node3(v1), mk.node3(n, v2._1(), v2._2()), mk.node2(v2._3(), v2._4()), m2); } }); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v1 = four.values(); return y.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one) { return append2(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), n, one.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { return append3(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node2(v1._4(), n), mk.node2(two.values()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { final V3<Node<V, A>> v2 = three.values(); return append3(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), n, v2._1()), mk.node2(v2._2(), v2._3()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v2 = four.values(); return append3(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), n, v2._1()), mk.node3(v2._2(), v2._3(), v2._4()), m2); } }); } }); } private static <V, A> FingerTree<V, Node<V, A>> append2(final Measured<V, A> m, final FingerTree<V, Node<V, A>> t1, final Node<V, A> n1, final Node<V, A> n2, final FingerTree<V, Node<V, A>> t2) { return t1.match(new F<Empty<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Empty<V, Node<V, A>> empty) { return t2.cons(n2).cons(n1); } }, new F<Single<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Single<V, Node<V, A>> single) { return t2.cons(n2).cons(n1).cons(single.value()); } }, new F<Deep<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Deep<V, Node<V, A>> deep) { return t2.match(new F<Empty<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Empty<V, Node<V, A>> empty) { return deep.snoc(n1).snoc(n2); } }, new F<Single<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Single<V, Node<V, A>> single) { return deep.snoc(n1).snoc(n2).snoc(single.value()); } }, new F<Deep<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Deep<V, Node<V, A>> deep2) { return new Deep<V, Node<V, A>>(m.nodeMeasured(), m.sum(m.sum(m.sum(deep.measure(), n1.measure()), n2.measure()), deep2.measure()), deep.prefix, addDigits2(m.nodeMeasured(), deep.middle, deep.suffix, n1, n2, deep2.prefix, deep2.middle), deep2.suffix); } }); } }); } private static <V, A> FingerTree<V, Node<V, Node<V, A>>> addDigits2(final Measured<V, Node<V, A>> m, final FingerTree<V, Node<V, Node<V, A>>> m1, final Digit<V, Node<V, A>> suffix, final Node<V, A> n1, final Node<V, A> n2, final Digit<V, Node<V, A>> prefix, final FingerTree<V, Node<V, Node<V, A>>> m2) { final MakeTree<V, Node<V, A>> mk = mkTree(m); return suffix.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one) { return prefix.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one2) { return append2(m, m1, mk.node2(one.value(), n1), mk.node2(n2, one2.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { return append2(m, m1, mk.node3(one.value(), n1, n2), mk.node2(two.values()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { return append2(m, m1, mk.node3(one.value(), n1, n2), mk.node3(three.values()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v2 = four.values(); return append3(m, m1, mk.node3(one.value(), n1, n2), mk.node2(v2._1(), v2._2()), mk.node2(v2._3(), v2._4()), m2); } }); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { final V2<Node<V, A>> v1 = two.values(); return prefix.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one) { return append2(m, m1, mk.node3(v1._1(), v1._2(), n1), mk.node2(n2, one.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two2) { final V2<Node<V, A>> v2 = two2.values(); return append2(m, m1, mk.node3(v1._1(), v1._2(), n1), mk.node3(n2, v2._1(), v2._2()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { final V3<Node<V, A>> v2 = three.values(); return append3(m, m1, mk.node3(v1._1(), v1._2(), n1), mk.node2(n2, v2._1()), mk.node2(v2._2(), v2._3()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v2 = four.values(); return append3(m, m1, mk.node3(v1._1(), v1._2(), n1), mk.node3(n2, v2._1(), v2._2()), mk.node2(v2._3(), v2._4()), m2); } }); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { final V3<Node<V, A>> v1 = three.values(); return prefix.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one) { return append2(m, m1, mk.node3(v1), mk.node3(n1, n2, one.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { return append3(m, m1, mk.node3(v1), mk.node2(n1, n2), mk.node2(two.values()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three2) { final V3<Node<V, A>> v2 = three2.values(); return append3(m, m1, mk.node3(v1), mk.node3(n1, n2, v2._1()), mk.node2(v2._2(), v2._3()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v2 = four.values(); return append3(m, m1, mk.node3(v1), mk.node3(n1, n2, v2._1()), mk.node3(v2._2(), v2._3(), v2._4()), m2); } }); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v1 = four.values(); return prefix.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one) { return append3(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node2(v1._4(), n1), mk.node2(n2, one.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { return append3(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), n1, n2), mk.node2(two.values()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { return append3(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), n1, n2), mk.node3(three.values()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four2) { final V4<Node<V, A>> v2 = four2.values(); return append4(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), n1, n2), mk.node2(v2._1(), v2._2()), mk.node2(v2._3(), v2._4()), m2); } }); } }); } @SuppressWarnings("unchecked") private static <V, A> FingerTree<V, Node<V, A>> append3(final Measured<V, A> m, final FingerTree<V, Node<V, A>> t1, final Node<V, A> n1, final Node<V, A> n2, final Node<V, A> n3, final FingerTree<V, Node<V, A>> t2) { final Measured<V, Node<V, A>> nm = m.nodeMeasured(); return t1.match(new F<Empty<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Empty<V, Node<V, A>> empty) { return t2.cons(n3).cons(n2).cons(n1); } }, new F<Single<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Single<V, Node<V, A>> single) { return t2.cons(n3).cons(n2).cons(n1).cons(single.value()); } }, new F<Deep<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Deep<V, Node<V, A>> deep) { return t2.match(new F<Empty<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Empty<V, Node<V, A>> empty) { return deep.snoc(n1).snoc(n2).snoc(n3); } }, new F<Single<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Single<V, Node<V, A>> single) { return deep.snoc(n1).snoc(n2).snoc(n3).snoc(single.value()); } }, new F<Deep<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Deep<V, Node<V, A>> deep2) { return new Deep<V, Node<V, A>>(nm, nm.monoid().sumLeft( list(deep.v, n1.measure(), n2.measure(), n3.measure(), deep2.v)), deep.prefix, addDigits3(nm, deep.middle, deep.suffix, n1, n2, n3, deep2.prefix, deep2.middle), deep2.suffix); } }); } }); } private static <V, A> FingerTree<V, Node<V, Node<V, A>>> addDigits3(final Measured<V, Node<V, A>> m, final FingerTree<V, Node<V, Node<V, A>>> m1, final Digit<V, Node<V, A>> suffix, final Node<V, A> n1, final Node<V, A> n2, final Node<V, A> n3, final Digit<V, Node<V, A>> prefix, final FingerTree<V, Node<V, Node<V, A>>> m2) { final MakeTree<V, Node<V, A>> mk = mkTree(m); return suffix.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one) { return prefix.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one2) { return append2(m, m1, mk.node3(one.value(), n1, n2), mk.node2(n3, one2.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { final V2<Node<V, A>> v2 = two.values(); return append2(m, m1, mk.node3(one.value(), n1, n2), mk.node3(n3, v2._1(), v2._2()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { final V3<Node<V, A>> v2 = three.values(); return append3(m, m1, mk.node3(one.value(), n1, n2), mk.node2(n3, v2._1()), mk.node2(v2._2(), v2._3()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v2 = four.values(); return append3(m, m1, mk.node3(one.value(), n1, n2), mk.node3(n3, v2._1(), v2._2()), mk.node2(v2._3(), v2._4()), m2); } }); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { final V2<Node<V, A>> v1 = two.values(); return prefix.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one) { return append2(m, m1, mk.node3(v1._1(), v1._2(), n1), mk.node3(n2, n3, one.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { return append3(m, m1, mk.node3(v1._1(), v1._2(), n1), mk.node2(n2, n3), mk.node2(two.values()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { final V3<Node<V, A>> v2 = three.values(); return append3(m, m1, mk.node3(v1._1(), v1._2(), n1), mk.node3(n2, n3, v2._1()), mk.node2(v2._2(), v2._3()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v2 = four.values(); return append3(m, m1, mk.node3(v1._1(), v1._2(), n1), mk.node3(n2, n3, v2._1()), mk.node3(v2._2(), v2._3(), v2._4()), m2); } }); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { return prefix.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one) { return append3(m, m1, mk.node3(three.values()), mk.node2(n1, n2), mk.node2(n3, one.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { return append3(m, m1, mk.node3(three.values()), mk.node3(n1, n2, n3), mk.node2(two.values()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three2) { return append3(m, m1, mk.node3(three.values()), mk.node3(n1, n2, n3), mk.node3(three2.values()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v2 = four.values(); return append4(m, m1, mk.node3(three.values()), mk.node3(n1, n2, n3), mk.node2(v2._1(), v2._2()), mk.node2(v2._3(), v2._4()), m2); } }); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v1 = four.values(); return prefix.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one) { return append3(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), n1, n2), mk.node2(n3, one.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { final V2<Node<V, A>> v2 = two.values(); return append3(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), n1, n2), mk.node3(n3, v2._1(), v2._2()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { final V3<Node<V, A>> v2 = three.values(); return append4(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), n1, n2), mk.node2(n3, v2._1()), mk.node2(v2._2(), v2._3()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four2) { final V4<Node<V, A>> v2 = four2.values(); return append4(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), n1, n2), mk.node3(n3, v2._1(), v2._2()), mk.node2(v2._3(), v2._4()), m2); } }); } }); } @SuppressWarnings("unchecked") private static <V, A> FingerTree<V, Node<V, A>> append4(final Measured<V, A> m, final FingerTree<V, Node<V, A>> t1, final Node<V, A> n1, final Node<V, A> n2, final Node<V, A> n3, final Node<V, A> n4, final FingerTree<V, Node<V, A>> t2) { final Measured<V, Node<V, A>> nm = m.nodeMeasured(); return t1.match(new F<Empty<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Empty<V, Node<V, A>> empty) { return t2.cons(n4).cons(n3).cons(n2).cons(n1); } }, new F<Single<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Single<V, Node<V, A>> single) { return t2.cons(n4).cons(n3).cons(n2).cons(n1).cons(single.value()); } }, new F<Deep<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Deep<V, Node<V, A>> deep) { return t2.match(new F<Empty<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Empty<V, Node<V, A>> empty) { return t1.snoc(n1).snoc(n2).snoc(n3).snoc(n4); } }, new F<Single<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Single<V, Node<V, A>> single) { return t1.snoc(n1).snoc(n2).snoc(n3).snoc(n4).snoc(single.value()); } }, new F<Deep<V, Node<V, A>>, FingerTree<V, Node<V, A>>>() { public FingerTree<V, Node<V, A>> f(final Deep<V, Node<V, A>> deep2) { return new Deep<V, Node<V, A>>(nm, m.monoid().sumLeft( list(deep.v, n1.measure(), n2.measure(), n3.measure(), n4.measure(), deep2.v)), deep.prefix, addDigits4(nm, deep.middle, deep.suffix, n1, n2, n3, n4, deep2.prefix, deep2.middle), deep2.suffix); } }); } }); } private static <V, A> FingerTree<V, Node<V, Node<V, A>>> addDigits4(final Measured<V, Node<V, A>> m, final FingerTree<V, Node<V, Node<V, A>>> m1, final Digit<V, Node<V, A>> suffix, final Node<V, A> n1, final Node<V, A> n2, final Node<V, A> n3, final Node<V, A> n4, final Digit<V, Node<V, A>> prefix, final FingerTree<V, Node<V, Node<V, A>>> m2) { final MakeTree<V, Node<V, A>> mk = mkTree(m); return suffix.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one) { return prefix.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one2) { return append2(m, m1, mk.node3(one.value(), n1, n2), mk.node3(n3, n4, one2.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { return append3(m, m1, mk.node3(one.value(), n1, n2), mk.node2(n3, n4), mk.node2(two.values()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { final V3<Node<V, A>> v2 = three.values(); return append3(m, m1, mk.node3(one.value(), n1, n2), mk.node3(n3, n4, v2._1()), mk.node2(v2._2(), v2._3()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v2 = four.values(); return append3(m, m1, mk.node3(one.value(), n1, n2), mk.node3(n3, n4, v2._1()), mk.node3(v2._2(), v2._3(), v2._4()), m2); } }); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { final V2<Node<V, A>> v1 = two.values(); return prefix.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one) { return append3(m, m1, mk.node3(v1._1(), v1._2(), n1), mk.node2(n2, n3), mk.node2(n4, one.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two2) { return append3(m, m1, mk.node3(v1._1(), v1._2(), n1), mk.node3(n2, n3, n4), mk.node2(two2.values()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { return append3(m, m1, mk.node3(v1._1(), v1._2(), n1), mk.node3(n2, n3, n4), mk.node3(three.values()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v2 = four.values(); return append4(m, m1, mk.node3(v1._1(), v1._2(), n1), mk.node3(n2, n3, n4), mk.node2(v2._1(), v2._2()), mk.node2(v2._3(), v2._4()), m2); } }); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { final V3<Node<V, A>> v1 = three.values(); return prefix.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one) { return append3(m, m1, mk.node3(v1), mk.node3(n1, n2, n3), mk.node2(n4, one.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { final V2<Node<V, A>> v2 = two.values(); return append3(m, m1, mk.node3(v1), mk.node3(n1, n2, n3), mk.node3(n4, v2._1(), v2._2()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { final V3<Node<V, A>> v2 = three.values(); return append4(m, m1, mk.node3(v1), mk.node3(n1, n2, n3), mk.node2(n4, v2._1()), mk.node2(v2._2(), v2._3()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v2 = four.values(); return append4(m, m1, mk.node3(v1), mk.node3(n1, n2, n3), mk.node3(n4, v2._1(), v2._2()), mk.node2(v2._3(), v2._4()), m2); } }); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v1 = four.values(); return prefix.match(new F<One<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final One<V, Node<V, A>> one) { return append3(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), n1, n2), mk.node3(n3, n4, one.value()), m2); } }, new F<Two<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Two<V, Node<V, A>> two) { return append4(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), n1, n2), mk.node2(n3, n4), mk.node2(two.values()), m2); } }, new F<Three<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Three<V, Node<V, A>> three) { final V3<Node<V, A>> v2 = three.values(); return append4(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), n1, n2), mk.node3(n3, n4, v2._1()), mk.node2(v2._2(), v2._3()), m2); } }, new F<Four<V, Node<V, A>>, FingerTree<V, Node<V, Node<V, A>>>>() { public FingerTree<V, Node<V, Node<V, A>>> f(final Four<V, Node<V, A>> four) { final V4<Node<V, A>> v2 = four.values(); return append4(m, m1, mk.node3(v1._1(), v1._2(), v1._3()), mk.node3(v1._4(), n1, n2), mk.node3(n3, n4, v2._1()), mk.node3(v2._2(), v2._3(), v2._4()), m2); } }); } }); } }