Splitting an Eithers List in Java

In general, as an academic exercise, I am experimenting with my own implementation Eitherin Java inspired by Haskell Either( https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Either.html )

I have a working implementation that I am pleased with:

    Either<String, Integer> either = Either.left(A_STRING);
    assertThat(either.left(), is(A_STRING));
    assertThat(either.isLeft(), is(true));
    assertThat(either.isRight(), is(false));
    assertThat(either.map(x -> AN_INTEGER, y -> A_LONG), is(Either.left(AN_INTEGER)));
    assertThat(either.consolidate(x -> A_LONG, y -> ANOTHER_LONG), is(A_LONG));

Equivalent Haskell leftsand rightsis in flow filtration:

 Stream<String> s = streamOfEithers
     .filter(Either::isLeft)
     .map( x -> x.left())

The problem is creating the Haskell equivalent partitionEithers.

My first instinct was:

  streamOfEithers.collect(Collectors.groupingBy(Either::isLeft))

However, this seems to lose my types - it returns Map<Boolean, Either<? extends Object, ? extends Object>>, not (for example) Map<Boolean, Either<String,Integer>.

Of course, ideally, the result of the partition is not two lists Eithers, but two lists, one from each type. Java does not have a class Pair<T,U>, but if possible, it is possible:

 List<Either<String,Integer>> listOfEithers = ...
 Pair<List<String>,List<Integer>> partitioned = Either.partitionList(listOfEithers);

:

 Map<Boolean, Either<String,Integer>> partitioned = Either.partitionList(listOfEithers);

... .

Pair Pair (, , Pair, " , " ), Haskell partitionEithers?

+4
3

Pair, Either, , . :

class Aggregate<T, U> {
    List<T> tList = new ArrayList<>();
    List<U> uList = new ArrayList<>();

    public void add(Either<T, U> e) {
        if(e.isLeft()) {
            tList.add(e.left());
        } else {
            uList.add(e.right());
        }
    }

    public Aggregate<T, U> combine(Aggregate<T, U> other) {
        tList.addAll(other.tList);
        uList.addAll(other.uList);
        return this; // could create a new Aggregate here instead...
    }

    public static <T, U> Collector<Either<T,U>, ? , Aggregate<T, U>> partitionEithers() {
        return Collector.of(Aggregate::new, Aggregate::add, Aggregate::combine);
    }
}

:

Aggregate<String, Integer> result = streamOfEithers.collect(Aggregate.partitionEithers());
+2

:

Map<Boolean, List<Either<Integer, String>>> collect = list.stream().collect(Collectors.partitioningBy(Either::isLeft));

, "" - Either<L,R> ( , ), , , .

Pair :

Pair<List<Integer>, List<String>> result =
      pair(
          collect.getOrDefault(true, Collections.emptyList()).stream().map(Either::left).collect(toList()),
          collect.getOrDefault(false, Collections.emptyList()).stream().map(Either::right).collect(toList()));
+1

Haskell, .

Java-.

streamOfEithers.collect(Collectors.groupingBy(Either::isLeft))

Map<Boolean, Either<? extends Object, ? extends Object>>

- - . , java (, ++). - , . , .

0

Source: https://habr.com/ru/post/1667994/


All Articles