2

I have this code to transform List[Future[Int]] to Future[List[Int]] by using scalaz sequence.

import scalaz.concurrent.Future

val t = List(Future.now(1), Future.now(2), Future.now(3)) //List[Future[Int]]
val r = t.sequence //Future[List[Int]]

because I am using Future from scalaz, so it may have implicit resolution to do the magic for me, I just wonder if the type class is custom class not predefined one like Future, how can I define implicit resolution to achieve the same result

case class Foo(x: Int)

val t = List(Foo(1), Foo(2), Foo(3)) //List[Foo[Int]]

val r = t.sequence //Foo[List[Int]]

Many thanks in advance

Xiaohe Dong
  • 4,953
  • 6
  • 24
  • 53

1 Answers1

3

You need to create an Applicative[Foo] (or a Monad[Foo]) which is in implicit scope.

What you are asking for exactly won't work, since your Foo is not universally quantified (so your expected type for r doesn't make sense as Foo[List[Int]], since Foo doesn't take a type parameter.

Lets define Foo differently:

case class Foo[A](a: A)

object Foo {
  implicit val fooApplicative = new Applicative[Foo] {
      override def point[A](a: => A) = Foo(a)
      override def ap[A,B](fa: => Foo[A])(f: => Foo[A=>B]): Foo[B] = Foo(f.a(fa.a))
  } 
}

Now if we make sure this implicit is in scope, we can sequence:

scala> val t = List(Foo(1), Foo(2), Foo(3)) 
t: List[Foo[Int]] = List(Foo(1), Foo(2), Foo(3))

scala> t.sequence
res0: Foo[List[Int]] = Foo(List(1, 2, 3))
Chirlo
  • 5,989
  • 1
  • 29
  • 45
stew
  • 11,276
  • 36
  • 49
  • thanks for your answer, one typo is override def point(a: => A) = Foo(a) should be changed to override def point[A](a: => A) = Foo(a). – Xiaohe Dong Oct 29 '14 at 23:52