Either implementation in Vavr library

An idea behind the Either type

service.someOperation(result -> {
if (result.succeded()){
// do something
} else {
// failure
}
});
FileReadService service = new FileReadService();
try {
String content = service.readFile("no-such-file.txt");
return content;
} catch (BadFilenameException ex){
System.out.println("No file found");
return readFromCache();
}
FileReadService service = new FileReadService();
String content = service.readFileSafely("no-such-file.txt").getOrElse(readFromCache());
Either<List<ValidatonError>, Invoice> = validator.validate(invoice);
  • You don’t need to create different return types for each occasion, so you code will become more lightweight
  • Either makes your codebase more unified and mantainable
  • Either class includes a number of useful methods, which incorporate it into functional pipelines

How to map results

  • Left value = a failure case result
  • Right value = a success case result
StudentService service = new StudentService();List<Student> students = service.findStudentsWithEither("HISTORY201")
.map(res -> res.filter(student -> student.getGpa() > 4.0))
.getOrElse(List.empty());
assertThat(students).isNotEmpty().hasSize(5);
  1. Map each student entity as his/her GPA score
  2. Use a built-in function average() from a Vavr List
BigDecimal average = service.findStudentsWithEither("ART101")
.map(res -> res.map(student -> student.getGpa()))
.map(res -> res.average())
.get()
.map(value -> new BigDecimal(value, new MathContext(2)))
.getOrElse(BigDecimal.ZERO);
assertThat(average).isEqualByComparingTo("3.9");

Validate results with filter()

StudentService service = new StudentService();
BigDecimal average = service.findStudentsWithEither("MATH201")
.filter(students -> students.nonEmpty())
.get()
.map(res -> res.map(student -> student.getGpa()))
.map(res -> res.average())
.get()
.map(value -> new BigDecimal(value, new MathContext(2)))
.get();
assertThat(average).isEqualByComparingTo("3.9");

Other notable methods

  • peek() = this method executes a Consumer function on the right value, but does not modify it, like map() (there is also peekLeft() method for a left case)
  • sequence() = if you have a sequence of Either, this method reduces them into a single Either instance. The result is Either that holds sequences for left and right values of all members
  • swap() = you can swap a left and a right value, so Either<A,B> will become Either<B,A>

Source code

Summary

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store