Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining Either's in Vavr?

I have a couple of Vavr Either's and I want to invoke a function with the Right value for each of these Either's. For example:

Either<MyError, String> either1 = ..
Either<MyError, String> either2 = ..
Either<MyError, String> either3 = ..

Either<MyError, String>> methodRequiringAllInputs(String, String, String) { 
..
}

I could of course do something like this:

either1.flatMap { value1 ->
    either2.flatMap { value2 ->
        either3.flatMap { value3 ->
            methodRequiringAllInputs(value1, value2, value3);
        }
    }
}

But this is very ugly. In other languages you could just use something like do-notation or for comprehensions to flatten out the structure. I know that Vavr has the concept of a Validation which is an applicative functor that allows you to do:

Validation<MyError, String> validation1 = ..
Validation<MyError, String> validation2 = ..
Validation<MyError, String> validation3 = ..

Validation.combine(validation1, validation2, validation3)
          .ap((validationValue1,validationValue2,validationValue3) -> .. );  

which is much nicer.

My question is if something similar exists in Vavr for Either's to avoid the nested flatMap structure? Note that I don't want to convert the Either's to Validation's.

like image 766
Johan Avatar asked Jan 09 '20 09:01

Johan


People also ask

How do you use VAVR either?

By convention, Either's Left attribute represents a failure case and the Right one represents a success. However, based on our needs we can change this using projections – Either in Vavr is not biased towards Left or Right. If we project to Right, operations like filter(), map() will have no effect if Either was Left.

Why should I use VAVR?

It helps to reduce the amount of code and to increase the robustness. A first step towards functional programming is to start thinking in immutable values. Vavr provides immutable collections and the necessary functions and control structures to operate on these values. The results are beautiful and just work.

What is VAVR io?

Vavr is a functional library for Java 8+ that provides immutable data types and functional control structures.


1 Answers

There's a for comprehension construct in vavr that you could use for your use case. It helps you transform multiple Iterable, Option, Try, Future or List instances to another Iterator, Option, Try, Future or List instance respectively, by combining them (as rows of their cartesian product) into result values.

In your case, Either being an Iterable on the right value, you can use the For construct for Iterables to construct a Tuple3 of the String right values, and iterate over the resulting Iterator by invoking your side-effecting code, or mapping/transforming them in whatever way you want. You will have a rich vavr Iterator, so that's a lot more flexible than a simple JDK Iterator.

import static io.vavr.API.For;

For(either1, either2, either3)
    .yield(Tuple::of)
    .forEach(t -> methodRequiringAllInputs(t._1, t._2, t._3));

One small note though: in the above case, the result from the yield is a lazily evaluated Iterator. That means you'll need to iterate over it in the end in order to have the effects executed, so the forEach part is essential. You cannot move the side-effecting code into the yield part and skip the forEach, as the yield part will only be (lazily) executed when the resulting Iterator is being iterated over.

like image 132
Nándor Előd Fekete Avatar answered Sep 23 '22 17:09

Nándor Előd Fekete