List[OptionT[Future, Int]] 到 OptionT[Future, List[A]]
List[OptionT[Future, Int]] to OptionT[Future, List[A]]
我正在构建 Int
的 List
,使用异步计算来检索元素:
(1 to n).map(anAsyncThingy).toList
其中 anAsyncThingy
returns OptionT[Future, Int]
因此结果的类型是 List[OptionT[Future, Int]]
我现在想要的是一个OptionT[Future, List[A]]
这是我迄今为止最好的尝试(我将添加一些存根,以便它可以 运行 在 REPL 中)
import scalaz._; import Scalaz._
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
def anAsyncThingy(x: Int): OptionT[Future, Int] = x.point[Future].liftM[OptionT]
val res = OptionT {
Future.sequence {
(1 to 3).map(anAsyncThingy(_).run).toList
}.map(_.sequence)
}
res.map(println) // List(1, 2, 3)
以上按预期工作,但我觉得使用适当的 scalaz 构造有很大的改进空间,而不是从 monad 变换器中跳进跳出。
如何以更直接的方式获得相同的结果?
经过一些试验,我自己找到了答案:
val res = (1 to 3).map(anAsyncThingy).toList.sequenceU
res.map(println) // List(1, 2, 3)
为 scalaz 欢呼!
顺便说一句,需要 sequenceU
而不是 sequence
因为 scala 不够聪明,无法弄清楚你什么时候有
OptionT[M, A]
如果您修复类型参数(例如 M
到 Future
)
OptionT[Future, A]
它的形状是M[_]
编译器一直相信它具有 M[_, _]
形状,除非用勺子喂食(使用讨厌的 lambda 类型)
这里是 scalaz 的 sequenceU
介入并使用 Unapply
解决此问题的地方。有关该主题的更多信息 here。
更新
根据 phadej 的评论,sequence ∘ map ≡ traverse
,因此可以使用 traverseU
:
使其更加简洁
(1 to 3).toList.traverseU(anAsyncThingy)
sequence
与 sequenceU
的相同想法当然适用于 traverse
与 traverseU
。
我正在构建 Int
的 List
,使用异步计算来检索元素:
(1 to n).map(anAsyncThingy).toList
其中 anAsyncThingy
returns OptionT[Future, Int]
因此结果的类型是 List[OptionT[Future, Int]]
我现在想要的是一个OptionT[Future, List[A]]
这是我迄今为止最好的尝试(我将添加一些存根,以便它可以 运行 在 REPL 中)
import scalaz._; import Scalaz._
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
def anAsyncThingy(x: Int): OptionT[Future, Int] = x.point[Future].liftM[OptionT]
val res = OptionT {
Future.sequence {
(1 to 3).map(anAsyncThingy(_).run).toList
}.map(_.sequence)
}
res.map(println) // List(1, 2, 3)
以上按预期工作,但我觉得使用适当的 scalaz 构造有很大的改进空间,而不是从 monad 变换器中跳进跳出。
如何以更直接的方式获得相同的结果?
经过一些试验,我自己找到了答案:
val res = (1 to 3).map(anAsyncThingy).toList.sequenceU
res.map(println) // List(1, 2, 3)
为 scalaz 欢呼!
顺便说一句,需要 sequenceU
而不是 sequence
因为 scala 不够聪明,无法弄清楚你什么时候有
OptionT[M, A]
如果您修复类型参数(例如 M
到 Future
)
OptionT[Future, A]
它的形状是M[_]
编译器一直相信它具有 M[_, _]
形状,除非用勺子喂食(使用讨厌的 lambda 类型)
这里是 scalaz 的 sequenceU
介入并使用 Unapply
解决此问题的地方。有关该主题的更多信息 here。
更新
根据 phadej 的评论,sequence ∘ map ≡ traverse
,因此可以使用 traverseU
:
(1 to 3).toList.traverseU(anAsyncThingy)
sequence
与 sequenceU
的相同想法当然适用于 traverse
与 traverseU
。