【问题标题】:How to use sequence from scalaz to transform T[G[A]] to G[T[A]]如何使用 scalaz 中的序列将 T[G[A]] 转换为 G[T[A]]
【发布时间】:2014-10-29 00:21:43
【问题描述】:

我有这段代码通过使用 scalaz 序列将 List[Future[Int]] 转换为 Future[List[Int]]。

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

因为我使用的是来自scalaz的Future,所以它可能有隐式解析来为我做魔法,我只是想知道类型类是否是自定义类而不是像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]]

在此先感谢

【问题讨论】:

    标签: scala scalaz scalaz7


    【解决方案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))
    

    【讨论】:

    • 感谢您的回答,一个错字是 override def point(a: => A) = Foo(a) 应该改为 override def point[A](a: => A) = Foo (一)。
    猜你喜欢
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 2021-02-02
    • 2019-01-07
    • 2019-02-01
    • 2013-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多