Either { public static <C, D> Either<C, D> createLeft(C value) { return new Left<>(value); }  static Either<C, D> createLeft(C value); static Either<C, D> createRight(D value); static Either<C, D> createRight(Optional<D> value, C ifNotPresent); static Either<C, D> createRight(Optional<D> value, Supplier<C> ifNotPresent); abstract boolean isLeft(); abstract boolean isRight(); LeftProjection<A, B> left(); RightProjection<A, B> right(); abstract A leftValue(); abstract B rightValue(); abstract Either<B, A> swap(); abstract Either<A, C> leftOnly(); abstract Either<C, B> rightOnly(); Either<A, C> map(Function<B, C> functor); abstract Either<C, D> bimap(Function<A, C> leftMap, Function<B, D> rightMap); abstract C reduce(Function<A, C> leftReduce, Function<B, C> rightReduce); abstract double reduceToDouble(ToDoubleFunction<A> leftReduce, ToDoubleFunction<B> rightReduce); abstract int reduceToInt(ToIntFunction<A> leftReduce, ToIntFunction<B> rightReduce); abstract boolean reduceToBoolean(Predicate<A> leftReduce, Predicate<B> rightReduce); abstract B reduceLeft(Function<A, B> reduceLeft); abstract A reduceRight(Function<B, A> reduceRight); abstract void accept(Consumer<A> leftConsumer, Consumer<B> rightConsumer); abstract Either<A, C> flatMap(Function<B, Either<A, C>> mapper); abstract Optional<B> toOptional(); abstract boolean testEither(Predicate<A> leftCheck, Predicate<B> rightCheck); abstract Either<A, B> filter(Predicate<B> acceptor, A onNotAccepted); abstract Either<A, B> filter(Predicate<B> acceptor, Supplier<A> onNotAccepted);  }
@Test public void rightOnly_withLeft_fails() { Either<String, Integer> e = Either.createLeft("Hello"); assertThrows(IllegalStateException.class, e::rightOnly); }