Stream.flatMap signature is not correct
Remi Forax
forax at univ-mlv.fr
Fri Nov 30 17:44:40 PST 2012
Stream.flatMap is currently specified as:
<R> Stream<R> flatMap(FlatMapper<? super T, ? extends R> mapper);
but should be:
<R> Stream<R> flatMap(FlatMapper<? super T, ? super R> mapper);
and better (R is not a result but an item of the result sent as parameter of a block (hence the super)):
<U> Stream<U> flatMap(FlatMapper<? super T, ? super U> mapper);
with FlatMapper defined:
public interface FlatMapper<T, U> {
/**
* Map {@code element} and add all of the results to {@code sink}.
*
* @param sink Destination for mapped elements.
* @param element The element to be mapped.
*/
void flatMapInto(T element, Block<? super U> sink);
}
It's better to use something else than R because otherwise the signature
of map() and flatMap() are too similar despite working differently.
While it's a nice design, I'm not sure it's a good idea to include it
because I don't see how the compiler will be able to infer the type of U
(old S).
Here is an example (using the current API):
ArrayList<ClassMirror> set =
Mirrors.forClass(Object.class).methods().flatMap(
(block, method) -> { method.parameterTypes().forEach(block); }
).uniqueElements().into(new ArrayList<ClassMirror>());
I have re-implemented a small reflection API based on ASM using streams
to see how it goes.
Here the compiler can infer the type of method easily because it's the
type of the Stream,
but for block, I don't see how the compiler can find its type.
cheers,
Rémi
More information about the lambda-libs-spec-observers
mailing list