9

I have an instance of Either[Future[A], Future[B]] and I would like to transform it to Future[Either[A, B]].

Since my previous question, cats 0.8.1 has been released, changing the structure of the library and dropping Xor in favor of Either, which is right-biased in 2.12.

Thus the method described in the previous accepted answer does not work anymore. I have tried to find the appropriate imports but failed.

cats.instances.either._
cats.implicits._ 
cats.syntax.bitraverse._

looked plausible but unfortunately does not work. Compilation still fails with value bisequence is not a member of Either[scala.concurrent.Future[A],scala.concurrent.Future[‌​B]]

Widening the imports to *.all._ did not change the compiler error.

I am on scala 2.11.8 as not all libraries the project depends upon have released a version for 2.12

Community
  • 1
  • 1
kostja
  • 60,521
  • 48
  • 179
  • 224
  • 2
    `either.fold(_.map(Left(_)), _.map(Right(_)))`, but how is this related to cats? – Jean-Philippe Pellet Dec 16 '16 at 16:16
  • I've tried this with cats 0.8.1 and scala 2.11.8 and 2.12.1, and `bisequence` on `Either[Future[A], Future[B]]` works in both versions. Do you have an implicit `ExecutionContext` in scope? It's required for `Applicative[Future]` – Kolmar Dec 16 '16 at 16:55
  • @Kolmar - yes, I do import an implicit `ExecutionContext`. This is strange, have cleaned the project before compilation. Do you use the same 3 imports I did? – kostja Dec 16 '16 at 17:00
  • 1
    Deleted my answer. Sure looks like you're missing an import now that I figured out that there is syntax and instances for either of a `Bitraverse`. Try adding `import cats.syntax.either._` to see if that doesn't move it forward. – wheaties Dec 16 '16 at 17:03
  • 1
    Oh, I've reproduced your issue. Try with only a single import `cats.implicits._`. Seems your imports are interfering with each other. – Kolmar Dec 16 '16 at 17:04
  • @wheaties, Kolmar - thank you guys, conflicting imports have been the issue. My instinct was to widen the imports, not to narrow them down and this instinct was wrong. Your plain scala solution works great as well and I will be using it from now on. Travis Brown has provided a nice solution using cats to my previous question, so I tried to continue using it. – kostja Dec 16 '16 at 17:11
  • 1
    For posterity: [The Cats import guide](http://typelevel.org/cats/typeclasses/imports.html) – Peter Neyens Dec 16 '16 at 17:53
  • @PeterNeyens - ah, the last paragraph is golden :) thanks! – kostja Dec 16 '16 at 18:10

1 Answers1

5

have compiled the answers from the comments for reader convenience:

1: you can do it in plain scala (using cats.Functor for the definition here), courtesy of @wheaties & @jean-philippe-pellet

def eitherFmap[F[_], A, B](either: Either[F[A], F[B])(implicit F: Functor[F]): F[Either[A, B]] =   
either.fold(f => F.map(f)(Left(_)), f => F.map(f)(Right(_)))

2: cats bisequence refused to compile because of conflicting imports: a single import is enough here - courtesy of @kolmar

import cats.instances._
...
val futureOfEither = eitherOfFutures.bisequence

3: read the cats import guide to avoid the issue in the future - courtesy @peter-neyens

kostja
  • 60,521
  • 48
  • 179
  • 224