-1

I have this:

case class Sides[A](east: A, west: A)

I want to convert this Sides[Future[Boolean]] into this Future[Sides[Boolean]]

using Future.sequence how?

This is the docs:

def
sequence[A, M[X] <: TraversableOnce[X]](in: M[Future[A]])(implicit cbf: CanBuildFrom[M[Future[A]], A, M[A]], executor: ExecutionContext): Future[M[A]]
 Permalink
Simple version of Future.traverse. Transforms a TraversableOnce[Future[A]] into a Future[TraversableOnce[A]]. Useful for reducing many Futures into a single Future
user3995789
  • 3,452
  • 1
  • 19
  • 35
  • You need to implement `Traverse[Sides]`. It will not be `Future.sequence` (there is no such thing, without running the Future), but `Sides.sequence`. – Tomas Mikula Mar 04 '16 at 17:55
  • If you read the definition of `sequence` you'll see ```def sequence[A, M[X] <: TraversableOnce[X]](in: M[Future[A]])(implicit cbf: CanBuildFrom[M[Future[A]], A, M[A]], executor: ExecutionContext): Future[M[A]]``` So your `Sides` needs to be a subclass of `TraversableOnce`. – mfirry Mar 04 '16 at 18:03
  • @mfirry can you implement that please, I can't do `CanBuildFrom` thing. – user3995789 Mar 04 '16 at 18:10
  • 1
    Why do you want to use `Future.sequence`? If you are using `scala.concurrent.Future` won't something like this work: `def sequenceSides[A](sides: Sides[Future[A]])(implicit exec: ExecutionContext): Future[Sides[A]] = for { east <- sides.east; west <- sides.west } yield Sides(east, west)` ? – Kolmar Mar 04 '16 at 18:20
  • @Kolmar I have north south too and I want neat code. – user3995789 Mar 04 '16 at 18:28

1 Answers1

1

EDIT: Since this question has the scalaz tag, I was assuming that the Future in question was from scalaz. After the question has been edited, it is clear that the OP has Future from Scala standard library in mind.


I am expanding my comment as an answer. You need a Traverse instance for Sides, not Future. (There exists no Traverse instance for Future, unless you are willing to eagerly evaluate the Future.)

import scalaz.{Applicative, Traverse}
import scalaz.concurrent.Future
import scalaz.syntax.traverse._

case class Sides[A](east: A, west: A)

implicit def traverseSides: Traverse[Sides] = new Traverse[Sides] {
  def traverseImpl[G[_], A, B](s: Sides[A])(f: A => G[B])(implicit G: Applicative[G]): G[Sides[B]] =
    G.apply2(f(s.east), f(s.west))(Sides(_, _))
}

val sf: Sides[Future[Boolean]] = ???
vaf fs: Future[Sides[Boolean]] = sf.sequence
Tomas Mikula
  • 6,537
  • 25
  • 39
  • Thanks, this works, but, `Future sequence` doesn't eagerly evaluate I think that's what I want. – user3995789 Mar 04 '16 at 18:14
  • @user3995789 There has been a misunderstanding about which Future we were talking about. `Future.sequence[A, M[_]]` from stdlib uses the traversable structure of `M`, not `Future`, so it is consistent with what I said - that `Future` cannot be traversable unless you force it to evaluate. – Tomas Mikula Mar 04 '16 at 18:28