1

I have a Vavr Either that looks like this:

Either<DomainError, Boolean> maybePendingPayment = ...

I want to fold this response to return Either<DomainError, Optional>

return maybePendingPayment.fold(domainError -> domainError, pendingPayment ? GenericType.builder().build() : Optional.empty())

But it doesn't look like I can do this because fold wants me to return the same types:

[ERROR]     lower bounds: io.vavr.control.Either<xxx.yyy.DomainError,java.util.Optional<xxx.yyy.GenericType>>,java.lang.Object
[ERROR]     lower bounds: java.util.Optional<T>,java.util.Optional<T>,xxx.yyy.DomainError

Is there any way I can do this in a fancier way than just checking the left and right sides with an if-else?

coconut
  • 1,074
  • 4
  • 12
  • 30
  • 2
    A use case of `Either` is to encode computations that might yield an error. If you fold a value of this type you lose this abstraction and the need to handle errors pops up again. In order to make `fold` - the elimination rule of `Either` - type safe, both cases need to return a value of the same type. Usually a default value is used for the error case. If you don't have a meaningful default value, you should keep `Either` and instead lift functions into its context with functor, applicative and monad. –  Aug 25 '20 at 12:26
  • That makes a lot of sense. Thanks for the explanation @scriptum! – coconut Aug 25 '20 at 12:33

1 Answers1

2

Applying fold to your Either will (as the name already suggests) fold it and apply either the left or right function, returning the result of the applied function.

With the following example I tried to make more clear what is happening:

    public Optional<Object> verify() {
        Either<DomainError, Boolean> maybePendingPayment = Either.right(true);
        return maybePendingPayment.fold(Optional::of, pendingPayment -> pendingPayment ? Optional.of("pending payment") : Optional.empty());
    }

As you can see I chose Optional<Object> for the functions return type and wrapped the left function of the fold in an Optional as well. When unwrapping the Either your return type will either be the Optional<DomainError> or the result of the right function (in my example String or Optional.empty). If there is a common Supertype to what you are trying to return (between GenericType and DomainError), you could choose this one as a return type of the function instead of Object.

buettner123
  • 404
  • 4
  • 8