Cats Effect IO: создание IO с коллекциями Scala
Это игрушечная программа Scala, которая считывает с консоли 10 цифр и добавляет 1 к каждой из них:
import cats._
import cats.effect._
import cats.implicits._
object Main extends IOApp {
def printLine[A](x: A)(implicit show: Show[A]): IO[Unit] =
IO(println(show.show(x)))
def readLine(): IO[String] =
IO(scala.io.StdIn.readLine())
def readInts(n: Int): IO[List[Int]] =
List.fill(n)(readLine().map(_.toInt)).sequence
override def run(args: List[String]): IO[ExitCode] = {
for {
list <- readInts(10)
i <- list
_ <- printLine(i + 1)
} yield ExitCode.Success
}
}
Приведенный выше код не компилируется. Я получил:
[error] found : cats.effect.IO[cats.effect.ExitCode]
[error] required: scala.collection.GenTraversableOnce[?]
[error] _ <- printLine(i + 1)
Что я делаю неправильно?
1 ответ
Решение
Вы для понимания, это для вас IO
, но вы смешиваете это с List
, Чтобы сделать это немного понятнее, мы можем расширить для понимания, которое не будет компилироваться по той же причине, что вы не можете сгладить List
в IO
:
readInts(10).flatMap(list => list.flatMap(i => printLine(i + 1).map(_ => ExitCode.Success)))
Вместо этого попробуйте это:
for {
list <- readInts(10)
_ <- list.traverse(i => printLine(i + 1))
} yield ExitCode.Success
Обратите внимание, что это по сути то же самое, что и:
for {
list <- readInts(10)
_ <- list.map(i => printLine(i + 1)).sequence
} yield ExitCode.Success
traverse
просто сжимает map
а также sequence
ступает в одну. В любом случае, теперь ваше понимание правильно ограничено IO
,