Как использовать последовательность из 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 ответ:
Вам нужно создать
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))