前提
Javaの話。 Javaには今のところEitherは標準ライブラリとして入っていないので、vavrを使う。以前まではjavaslangと呼ばれていた。
単一のEither
Eitherというのは主にエラーか成功か、どちらかをもちますよという型として使う。
https://gist.github.com/asufana/341921ab2b31ecf2feb0
主にはこんな使い方をして、エラー処理に使う。
Either.java
Either<Exception, Integer> result = function();
if(result.isLeft()){
Exception ex = result.left().get();
}else{
Integer val = result.get();
}
複数のEither
しかし関数の結果というのは、配列であることも多くそうなるとこうなって一気に使う気をなくす。
Either2.java
List<Either<Exception, Integer>> result = function();
List<Exception> errors = result.stream().filter(e->e.isLeft()).map(e->e.left().get()).collect(toList());
List<Integer> success = result.stream().filter(e->e.isRight()).map(e->e.right().get()).collect(toList());
// do for error
// do for success
EitherList
ということで、このようなユーティリティを使うと楽に複数のListをまとめて扱えます。
EitherList.java
class EitherList<L, R> {
List<Either<L, R>> list;
public EitherList() {
list = new ArrayList<>();
}
public void add(Either<L, R> item) {
list.add(item);
}
public void addLeft(L item) {
list.add(Either.left(item));
}
public void addRight(R item) {
list.add(Either.right(item));
}
public void addLefts(List<L> items) {
items.forEach(this::addLeft);
}
public void addRights(List<R> items) {
items.forEach(this::addRight);
}
public static <L, R> EitherList<L, R> of(List<Either<L, R>> src) {
EitherList<L, R> dst = new EitherList<>();
src.forEach(e -> dst.add(e));
return dst;
}
public List<L> lefts() {
return list.stream()
.filter(e -> e.isLeft())
.map(e -> e.left().get())
.collect(toList());
}
public List<R> rights() {
return list.stream()
.filter(e -> e.isRight())
.map(e -> e.right().get())
.collect(toList());
}
}
main.java
public class Main {
public static void main(String[] args) {
List<Either<Exception, Integer>> list = new ArrayList<>();
list.add(Either.left(new Exception()));
list.add(Either.left(new Exception()));
list.add(Either.right(10));
list.add(Either.right(20));
EitherList<Exception, Integer> eitherList = EitherList.of(list);
List<Exception> errors = eitherList.lefts();
List<Integer> success = eitherList.rights();
}
}