flatMap 在 Scala 中
回想一下,理解只是对flatMap 的甜蜜调用:
for {
a <- expr //expr must return M[A] such that M has a
//flatMap method: flatMap[B](f: A => N[B]) for some N
b <- f(a) //f(a) must be an N[B]
...
您的问题
这是Iterator.flatMap的签名
def flatMap[B](f: A => GenTraversableOnce[B]): Iterator[B]
但您试图提供一个返回 IO[B] 的函数:
lst <- io //You cannot just have `io` on the right here
因此编译错误。
flatMap 再次在 Scala 中
Scala 的 flatMap <~> for-comprehension 转换应用于集合类型(和选项)(在我看来)令人困惑,因为它们允许您在不同类型的 Monad 之间切换(例如 List/Option/Set等等)。比如这里x的类型是什么?
val x =
for {
i <- List(1, 2, 3)
j <- Option(i + 1)
k <- Stream(i, j)
} yield k
scalaz 中的单子
仔细查看scalaz.Monad的flatMap:
trait Monad[M[_]] {
def flatMap[A, B](ma: M[A])(f: A => M[B]): M[B]
}
M 的类型始终是固定的。也就是说,在这种理解中:
lazy val ma: M[A] = ???
for (a <- ma; b <- f(a)) yield b
函数f的结果类型某些B必须在M[B]中。虽然有时这可能会有点烦人,但它具有完全可预测的优势。你永远不会对 你的 for 理解在什么 monad 中感到困惑。
回到问题
你想要什么并不明显,但这里有一些建议:
i.toStream.sequence.map(flatten) //IO[Stream[String]]