0

I have a value like this:

val ss: Option[Future[List[Either[Error, File]]]]

And what I want to do is to lift this to an EitherT.liftF[Future, Error, List[Either[Error, File]]] so what I did was this:

    ss match {
      case Some(value) => EitherT.liftF[Future, Error, List[Either[Error, File]]](value)
      case None        => EitherT.leftT[Future, List[Either[Error, File]]](Error("failed"))
    }

My question is whether it is correct that I can use EitherT.liftF to lift a value which is already a future because I think normally that is used for values which need to be lifted to a future, not one which is a future itself.

Ivan Kurchenko
  • 4,043
  • 1
  • 11
  • 28
Mojo
  • 1,152
  • 1
  • 8
  • 16
  • 1
    Yeah that is correct, that is the use of `EitherT.liftF` - check the docs:https://typelevel.org/cats/api/cats/data/EitherT$.html#liftF[F[_],A,B](fb:F[B])(implicitF:cats.Functor[F]):cats.data.EitherT[F,A,B] – Luis Miguel Mejía Suárez Feb 18 '20 at 16:29
  • 1
    Well a **Future** is not even cancelable in the first place... but being honest. no idea if using specifically a **Future** with **EitherT** can be problematic, I have never used futures in real code. – Luis Miguel Mejía Suárez Feb 18 '20 at 16:32

1 Answers1

0

Future has a Monad instance for practical reasons but isn't really lawful. See this post on the topic.

However it will still behave as expected in many cases such as yours.

You can also implement it this way:

EitherT(ss.toRight(Error("failed")).sequence)
montrivo
  • 165
  • 2
  • 7