title: how to upper-bound a self-referential type?
body: <p>I have things (say, for context, numbers) that can perform operations on their own type:</p>
  
  <pre><code>interface Number&lt;N&gt; {
      N add(N to);
  }
  class Int implements Number&lt;Int&gt; {
      Int add(Int to) {...}
  }
  </code></pre>
  
  <p>and actors that act on all subtypes of a certain upper bound:</p>
  
  <pre><code>interface Actor&lt;U&gt; {
      &lt;E extends U&gt; E act(Iterable&lt;? extends E&gt; items);
  }
  </code></pre>
  
  <p>I want to make an actor that acts polymorphically on any numerical type:</p>
  
  <pre><code>class Sum implements Actor&lt;Number&gt; {
      &lt;N extends Number&lt;N&gt;&gt; N act(Iterable&lt;? extends N&gt; items) {...}
  }
  </code></pre>
  
  <p>Now, clearly this doesn't work because <code>Number</code> and <code>Number&lt;N&gt;</code> are not the same. In fact, since <code>Number</code> doesn't constrain an implementor's type parameter to be its own type, such an actor could not possibly work. But I don't care to operate on <code>Number</code>s in general - I am satisfied for my functionality to work only on Numbers of some type <code>N extends Number&lt;N&gt;</code></p>
  
  <p>As an alternative, I could declare:</p>
  
  <pre><code>interface Actor&lt;E&gt; {
      E act(Iterable&lt;? extends E&gt; items);
  }
  
  class Sum&lt;N extends Number&lt;N&gt;&gt; implements Actor&lt;N&gt; {
      N act(Iterable&lt;? extends N&gt; items) {...}
  }
  </code></pre>
  
  <p>But this doesn't work for me because it forces me to know <code>N</code> when I construct my <code>Sum</code>, which my use case doesn't conveniently allow. It also forces an ugly <code>&lt;N extends Number&lt;N&gt;&gt;</code> on every class or method that polymorphically uses a <code>Sum</code>, causing a proliferation of type clutter.</p>
  
  <p>Is there any elegant way to do what I want?</p>
  
  <h2>Example:</h2>
  
  <p>Here is some sample code expressing what I would like to do.</p>
  
  <pre><code>interface Folder&lt;U&gt; {
      &lt;E extends U&gt; E fold(Iterable&lt;? extends E&gt; items);
  }
  
  class Sum implements Folder&lt;Number&gt; {
      &lt;N extends Number&lt;N&gt;&gt; N fold(Iterable&lt;? extends N&gt; items) {
          Iterator&lt;? extends N&gt; iter = items.iterator();
          N item = iter.next();
          while (iter.hasNext())
              item = item.add(iter.next());
          return item;
      }
  }
  
  class Concat implements Folder&lt;String&gt; {
      &lt;S extends String&gt; fold(Iterable&lt;? extends S&gt; items) {
          StringBuilder concatenation = new StringBuilder();
          for (S item : items)
              concatenation.append(item);
          return concatenation.toString();
      }
  }
  
  class FoldUtils {
      static &lt;U, E extends U&gt; E foldDeep(Folder&lt;U&gt; folder, Iterable&lt;? extends Iterable&lt;? extends E&gt;&gt; itemses) {
          Collection&lt;E&gt; partialResults = new ArrayList&lt;E&gt;();
          for (Iterable&lt;? extends E&gt; items : itemses)
              partialResults.add(folder.fold(items));
          return folder.fold(partialResults);
      }
  }
  </code></pre>