Cats Effect IO: создание IO с коллекциями Scala - PullRequest
0 голосов
/ 11 декабря 2018

Это игрушечная программа 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 Ответ

0 голосов
/ 11 декабря 2018

Ваш для понимания предназначен для IO, но вы смешиваете его с List.Чтобы сделать это немного понятнее, мы можем расширить для понимания, которое не будет компилироваться по той же причине, по которой вы не можете сгладить List в IO:

readInts(10).flatMap(list => list.flatMap(i => printLine(i + 1).map(_ => ExitCode.Success)))

Вместо этого попробуйтеthis:

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.

...