Scala 列表[OptionT[Future,Int]]至OptionT[Future,List[A]]
我正在使用异步计算来检索元素,构建一个Scala 列表[OptionT[Future,Int]]至OptionT[Future,List[A]],scala,scalaz,monad-transformers,Scala,Scalaz,Monad Transformers,我正在使用异步计算来检索元素,构建一个Int的列表: (1 to n).map(anAsyncThingy).toList 其中anAsyncThingy返回OptionT[Future,Int] 因此,结果的类型为List[OptionT[Future,Int] 我现在想要的是一个选项[未来,列表[A]] 这是我迄今为止最好的尝试(我将添加一些存根,以便它可以在REPL中运行) 上面的工作与预期的一样,但是我觉得使用适当的scalaz构造有很大的改进空间,而不是从monad Transfor
Int
的列表:
(1 to n).map(anAsyncThingy).toList
其中anAsyncThingy
返回OptionT[Future,Int]
因此,结果的类型为List[OptionT[Future,Int]
我现在想要的是一个选项[未来,列表[A]]
这是我迄今为止最好的尝试(我将添加一些存根,以便它可以在REPL中运行)
上面的工作与预期的一样,但是我觉得使用适当的scalaz构造有很大的改进空间,而不是从monad Transformer跳进跳出
我怎样才能以更直接的方式获得相同的结果?经过一些实验,我自己找到了答案:
val res = (1 to 3).map(anAsyncThingy).toList.sequenceU
res.map(println) // List(1, 2, 3)
对斯卡拉兹来说太好了
顺便说一句,sequenceU
是需要的,而不是sequence
,因为scala不够聪明,无法判断何时有
OptionT[M, A]
如果您修复了一个类型参数(M
到Future
)
它的形状为M[\u]
编译器一直认为它有一个M[\uu,\u]
形状,除非有勺子(带有讨厌的lambda类型)
这里是scalaz的sequenceU
的切入点,它使用Unapply
解决了这个问题。更多关于这个问题
更新
根据phadej的评论,顺序∘ 地图≡ traverse
,因此这可以通过traverseU
变得更加简洁:
(1 to 3).toList.traverseU(anAsyncThingy)
当然,sequence
vssequenceU
的相同概念也适用于traverse
vstraverseU
。作为旁注:sequence∘ 地图≡ 遍历
,所以我宁愿写:(1到3)。toList traverseU anAsyncThingy
OptionT[Future, A]
(1 to 3).toList.traverseU(anAsyncThingy)