Scala/Haskell の Either が便利であるため、これを自作してみようと思いました。

Either クラス実装

public final class Either<L,R> {
    private L left;
    private R right;
    private Either(L left, R right) {
        this.left = left;
        this.right = right;
    }
    public Optional<L> getLeft() {
        return Optional.ofNullable(left);
    }
    public Optional<R> getRight() {
        return Optional.ofNullable(right);
    }
    public static <L> Either<L,?> ofLeft(L left) {
        return new Either<>(left, null);
    }
    public static <R> Either<?,R> ofRight(R right) {
        return new Either<>(null, right);
    }
}

しかし、これは lambda で stream の中で利用しようとすると、下記のようにエラーが出ます。

実行ロジック

public class AppTest {

    public static void main(String[] args) {
        List<Integer> integerList = Arrays.asList(1, 2);
        List<Either<Integer, String>> eithers = integerList.stream()
                .map(i -> Either.ofLeft(i))
                .collect(Collectors.toList());
    }
}

発生コンパイルエラー

Error:(37, 25) java: 不適合な型: 推論変数Tには、不適合な境界があります
    等価制約: my.test.AppTest.Either<java.lang.Integer,java.lang.String>
    下限: my.test.AppTest.Either<java.lang.Integer,?のキャプチャ#1>

質問

  • このコンパイルエラーはなぜ発生するのでしょうか。また、どのように回避できるでしょうか。