title: Combining CompletableFutures into a tree-like Structure
body: <p>I'm currently experimenting with Java 8's Future API and in the Core CompleteableFuture. I know it is a monad, so it should have a bind-Operator.</p>
  
  <p>Now the idea is that I have a tree of abstract Operations k, e.g. like this:</p>
  
  <pre><code>O --- &gt; O3 ---&gt; O4 ---&gt; o5
    O ---&gt; o2 --/
  </code></pre>
  
  <p>I want to "merge" <code>O3</code> and <code>O2</code> into a new Operation  <code>O4 = (O3 o O2) (t) = O2(O3(t))</code>. 
  My idea is that I'm e.g. in <code>O2</code> and want to say: Merge the current node with <code>O3</code> and return a new node consisting of the concatenated operations.
  Unfortunately I've tried for the whole night now and I cannot figure it out.
  Also, for unknown reasons using the operator like <code>O1.mergeWith(O2).mergeWith(O3)</code> triggers the apply method twice for a singe invocation.</p>
  
  <p>The goal is to create a new function composed of other functions, so I can defer the calulation as far as possible.</p>
  
  <pre><code>public abstract class Operation&lt;T,R&gt; {
    // The value a
    private final CompletableFuture&lt;R&gt; future;
  
  // Executes the operation on t and returns something (maybe different) of type R
    protected abstract R apply(T t);
  
  // Gets the value of the future of this operation
    public R get() throws Exception {
      return future.get();
    }
  
    protected Operation(Supplier&lt;T&gt; s) {
      future =  CompletableFuture.supplyAsync(s).thenApplyAsync(transform());
    }
  
    protected Operation(CompletableFuture&lt;R&gt; f) {
      future = f;
    }
  
  
    CompletableFuture&lt;R&gt; createTargetFuture(R _value) {
      return CompletableFuture.supplyAsync(() -&gt; _value);
    }
  
    &lt;S&gt; Operation&lt;T,S&gt; mergeWith(Operation&lt;R,S&gt; _other) {
      CompletableFuture&lt;S&gt; _result = future.thenComposeAsync(
        // Method is synchronous, but is run async :) We need the createTargetFuture,         otherwise we cannot turn the constant t into a producer.
        (t) -&gt; _other.createTargetFuture(_other.apply(t)));
        //transform()).thenApplyAsync(_other.transform());
      return new Operation&lt;T, S&gt;(_result) {
        @Override
        protected S apply(T t) {
          // What to put here
          return null;
        }
      };
    }
  
    protected Function&lt;T,R&gt; transform(){
      return this::apply;
    }
  }
  </code></pre>