flatMap in scala
Recall that for-comprehensions are just sugared calls to 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]
...
Your question
Here is the signature of Iterator.flatMap
def flatMap[B](f: A => GenTraversableOnce[B]): Iterator[B]
But you were attempting to supply a function returning an IO[B]:
lst <- io //You cannot just have `io` on the right here
hence the compilation error.
flatMap in scala again
Scala's flatMap <~> for-comprehension conversions as they apply to collection types (and Option) are (in my opinion) confusing as they allow you to switch between different types of Monad (e.g. List/Option/Set etc). For example, what is the type of x here?
val x =
for {
i <- List(1, 2, 3)
j <- Option(i + 1)
k <- Stream(i, j)
} yield k
Monads in scalaz
Having a closer look at scalaz.Monad's flatMap:
trait Monad[M[_]] {
def flatMap[A, B](ma: M[A])(f: A => M[B]): M[B]
}
The type of M is always fixed. That is, in this comprehension:
lazy val ma: M[A] = ???
for (a <- ma; b <- f(a)) yield b
The result type of the function f must be in M[B] for some B. Whilst sometimes this can be a little irritating, it has the advantage of being completely predictable. You never get confused about what monad your for comprehension is in.
Back to the question
It is not obvious what you want, but here are a few suggestions:
i.toStream.sequence.map(flatten) //IO[Stream[String]]