【发布时间】:2018-12-11 19:18:33
【问题描述】:
我有包装列表的单子。我想将这些 monad 组合成一个 monad,将所有列表串联起来。
M[List[A]] + M[List[A]] ==> M[List[A]]
为了实现这一点,我做了以下(伪代码):
(1 to 10).foldLeft(Option(List(0)))((accumulator, i) => {
for {
prev <- accumulator
more <- Option(List(i))
} yield prev ++ more
})
这似乎可以编译,但我觉得它应该比这更简单和更短。有什么改进的想法吗?
【问题讨论】:
-
您要合并多少个列表?您的示例看起来好像只是
Monad[M].unit((1 to 10)),所以我根本不明白您想要在那里组合什么。 -
对不起,我不明白你在问什么。我想合并 11 个列表。
-
我在问您是否要将
(M[List[A]], M[List[A]])或List[M[List[A]]]合并到M[List[A]]中。您的第一个代码 sn-p 建议您要组合一对单子 (map2),第二个 sn-p 建议您要组合一系列单子 (sequence+map)。是哪一个? -
有什么区别?自然变换也是一样的。
-
不同之处在于
(M[List[A]], M[List[A]])可以转换为任何monad 的M[List[A]],而更一般的Foo[M[List[A]]]可以转换为M[List[A]],只有Foo是可遍历的。M是一个 monad 的事实并不能自动保证您可以将任意Foo[M[...]]交换为M[Foo[...]],并且任何Foo[List[A]]也不能折叠为List[A]。
标签: scala functional-programming monads applicative scala-cats