Как использовать последовательность из scalaz для преобразования Т [, Г []] В Г[Т[А]]


У меня есть этот код для преобразования List [Future[Int]] в Future [List[Int]] с помощью последовательности scalaz.

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]]

Поскольку я использую Future от scalaz, поэтому он может иметь неявное разрешение, чтобы сделать магию для меня, мне просто интересно, если класс типа является пользовательским классом, а не предопределенным, как Future, как я могу определить неявное разрешение для достижения того же результата

case class Foo(x: Int)

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

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

Заранее большое спасибо

1 2

1 ответ:

Вам нужно создать Applicative[Foo] (или Monad[Foo]), который находится в неявной области видимости.

То, что вы просите точно, не будет работать, так как ваш Foo не является универсально квантифицированным (поэтому ваш ожидаемый тип для r не имеет смысла как Foo[List[Int]], так как Foo не принимает параметр типа.

Давайте определим Foo иначе:

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))
  } 
}

Теперь, если мы убедимся, что это неявное находится в области видимости, мы можем последовательно:

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))