Vavr, Stream.unfold and type inference

(, de)

I came across Stream.unfold. It seems to be a good solution if you need to read paginated results from a service or database. You can pass the current page or result as parameter to the function that is called in the unfold expression.

Only, Java runs into a type constraint issue for functions that are not inlined lambdas. You’ll get something like: “Incompatible equality constraint” when trying to use a function reference in Stream.unfold, Stream.unfoldRight or Stream.unfoldLeft.

It took me some time to figure out that it boils down to (a valid) type constraint in the Java compiler. To actually get the desired result, the function signature needs to be adjusted. Let’s assume something like this:

FooBarRepository repo = new FooBarRepository();

List<String> result = Stream
        .unfoldRight(1, repo::generateChunk)
        .flatMap(List::toStream).take(50).toList();
result.forEach(e -> log.info("element: {}", e));

Instead of declaring the generateChunk function like this:

public Option<Tuple2<List<String>, Integer>> generateChunk(int counter) {
  //...
}

adapt the signature to:

public Option<Tuple2<? extends List<String>, ? extends Integer>> generateChunk(int counter) {
  //...
}