JEP 406 type inference

Vicente Romero vicente.romero at oracle.com
Thu Jul 8 02:24:46 UTC 2021


Hi,

I think that raw types are working against you, I tried this small 
variation of your code and it compiles:

import java.util.function.Function;

sealed interface Either<A, B> permits Either.Left, Either.Right {
     final record Left<A, B>(A a) implements Either<A, B> {}
     final record Right<A, B>(B b) implements Either<A, B> {}

     default <C> Either<C, B> first(Function<A, C> f) {
         return switch (this) {
             case Left<A, B> l -> new Left<C, B>(f.apply(l.a));
             case Right<A, B> r -> new Right<C, B>(r.b);
         };
     }
}

Thanks,
Vicente

On 7/7/21 10:00 PM, Jakob Brünker wrote:
> Hi all,
>
> I've been excited to try doing some things with JEP 406 for a while now,
> and when attempting to implement some things, I stumbled over an apparent
> shortcoming that surprised me:
>
> Compiling this code:
>
> import java.util.function.Function;
>
> sealed interface Either<A, B> permits Either.Left, Either.Right {
>      final record Left<A, B>(A a) implements Either<A, B> {}
>      final record Right<A, B>(B b) implements Either<A, B> {}
>
>      default <C> Either<C, B> first(Function<A, C> f) {
>          return switch (this) {
>              case Left l -> new Left<C, B>(f.apply(l.a));
>              case Right r -> new Right<C, B>(r.b);
>          };
>      }
> }
>
> with javac Either.java --enable-preview --release 18, results in
>
> Either.java:9: error: incompatible types: Object cannot be converted to A
>              case Left l -> new Left<C, B>(f.apply(l.a));
>                                                     ^
>    where A is a type-variable:
>      A extends Object declared in interface Either
> Either.java:10: error: incompatible types: Object cannot be converted to B
>              case Right r -> new Right<C, B>(r.b);
>                                               ^
>    where B is a type-variable:
>      B extends Object declared in interface Either
>
>
> It seems to determine that the field b of the Right record, which should be
> a B, is actually an Object, and similarly for Left.
>
> It's possible to implement this method with the visitor-pattern, but I
> would have expected this to be equivalent.
>
> Is this intentional?
>
> Cheers,
> Jakob



More information about the amber-dev mailing list