【问题标题】:Cats Effect IO: Compose IO with Scala collectionsCats Effect IO:使用 Scala 集合组合 IO
【发布时间】:2018-12-11 18:32:48
【问题描述】:

这是一个玩具 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)

我做错了什么?

【问题讨论】:

    标签: scala functional-programming scala-cats cats-effect


    【解决方案1】:

    你的理解是你的IO,但是你把它和List混在一起了。为了更清楚一点,我们可以扩展 for 理解,因为不能将 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 只是将mapsequence 步骤压缩为一个。无论哪种情况,现在您的 for 理解都正确限制为 IO

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-03
      相关资源
      最近更新 更多