Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EitherT: Call function returning Either only if a certain condition is true (otherwise return right)

So I have a certain function which I need to call only if a certain condition is true. If it's false, I consider it as Right.

I would use EitherT.cond, but the thing is my function's return type is Future[Either[ErrorType, Unit]], so it's not suitable for me. Here's my code which does what I want:

def callEitherFunction: Future[Either[ErrorType, Unit]]

for {
_ <- if (condition) {
     EitherT(callEitherFunction)
   } else {
     Either.right[ErrorType, Unit](()).toEitherT[Future]
   }
} yield {
  //Some actions
}

I wonder if there is a more elegant way to do it. Would appreciate any help.

like image 269
Anastasia Avatar asked Jul 15 '19 14:07

Anastasia


1 Answers

You can use EitherT.cond as follows:

cond[Future](!condition, (), ()).leftFlatMap(_ => EitherT(callEitherFunction))

Also, [Future] can be omitted in some contexts, making it even shorter.

I'm not sure whether it's all that much clearer than the if-else, though: the slightly longer version with if-else might be easier to understand and to maintain in the long run.


Complete example with all imports:

import cats.data.EitherT
import scala.concurrent.Future
import scala.util.Either
import cats.syntax.either._
import cats.instances.future._
import scala.concurrent.ExecutionContext.Implicits.global

type ErrorType = String
def callEitherFunction: Future[Either[ErrorType, Unit]] = ???
def condition: Boolean = true

EitherT.cond(!condition, (), ()).leftFlatMap(_ => EitherT(callEitherFunction))
like image 175
Andrey Tyukin Avatar answered Sep 21 '22 06:09

Andrey Tyukin