Ejemplo n.º 1
0
 /**
  * Puts the elements of the tree into a Stream, in pre-order.
  *
  * @return The elements of the tree in pre-order.
  */
 public Stream<A> flatten() {
   final F2<Tree<A>, P1<Stream<A>>, Stream<A>> squish =
       new F2<Tree<A>, P1<Stream<A>>, Stream<A>>() {
         public Stream<A> f(final Tree<A> t, final P1<Stream<A>> xs) {
           return cons(
               t.root(),
               t.subForest()
                   .map(
                       Stream.<Tree<A>, Stream<A>>foldRight()
                           .f(F2Functions.curry(this))
                           .f(xs._1())));
         }
       };
   return squish.f(this, P.p(Stream.nil()));
 }
Ejemplo n.º 2
0
 /**
  * Creates a new tree given a root and a (potentially infinite) subforest.
  *
  * @param root The root element of the tree.
  * @param forest A stream of the tree's subtrees.
  * @return A newly sprouted tree.
  */
 public static <A> Tree<A> node(final A root, final Stream<Tree<A>> forest) {
   return new Tree<>(root, P.p(forest));
 }
Ejemplo n.º 3
0
 /**
  * Folds a Tree<A> into a Tree<B> by applying the function f from the bottom of the Tree to the
  * top
  *
  * @param t A tree to fold from the bottom to the top.
  * @param f A function transforming the current node and a stream of already transformed nodes
  *     (its children) into a new node
  * @return The folded tree
  */
 public static <A, B> Tree<B> bottomUp(Tree<A> t, final F<P2<A, Stream<B>>, B> f) {
   final F<Tree<A>, Tree<B>> recursiveCall = a -> bottomUp(a, f);
   final Stream<Tree<B>> tbs = t.subForest()._1().map(recursiveCall);
   return node(f.f(P.p(t.root(), tbs.map(Tree.getRoot()))), tbs);
 }
Ejemplo n.º 4
0
 /**
  * Applies the given function to all subtrees of this tree, returning a tree of the results
  * (comonad pattern).
  *
  * @param f A function to bind across all the subtrees of this tree.
  * @return A new tree, with the results of applying the given function to each subtree of this
  *     tree. The result of applying the function to the entire tree is the root label, and the
  *     results of applying to the root's children are labels of the root's subforest, etc.
  */
 public <B> Tree<B> cobind(final F<Tree<A>, B> f) {
   return unfoldTree((Tree<A> t) -> P.p(f.f(t), t.subForest())).f(this);
 }