首页 > 解决方案 > 如何使用 IO Monad 退出 For-Comprehension

问题描述

当用户输入“停止”并使 readLn 异步时,我想在退出时进行无限读取打印循环。

import cats.effect.{ExitCode, IO, IOApp, Timer}

import scala.concurrent.duration._
import scala.io.StdIn
import scala.language.postfixOps
import cats.implicits._

object ReadWrite extends IOApp {
  val readLn: IO[String] = IO(StdIn.readLine())
  val readWriteName: IO[Nothing] = for {
    _     <- IO(println("write your name: "))
    name  <- readLn
    _     <- IO(println(s"Hello, $name"))
    t     <- name match {
      case "stop" => ???
      case _      =>  readWriteName
    }
  } yield t

  def run(args: List[String]): IO[ExitCode] =
    for {
      _ <- (Timer[IO].sleep(1 millisecond) *> readWriteName).start
      _ <- Timer[IO].sleep(100 second)
    } yield ExitCode.Success
}

我尝试使用IO(println(s"Buy Buy"))但有错误信息:

Error:(20, 11) type mismatch;
 found   : t.type (with underlying type Unit)
 required: Nothing
  } yield t

如何在没有错误的情况下退出?

例如,我还想在另一个线程中执行 IO readLn

标签: scalaiocats-effect

解决方案


将类型更改readWriteNameIO[Unit]

val readWriteName: IO[Unit] = for {
  _     <- IO(println("write your name: "))
  name  <- readLn
  _     <- IO(println(s"Hello, $name"))
  t     <- name match {
    case "stop" => IO(println(s"Buy Buy"))
    case _      =>  readWriteName
  }
} yield t

关于线程,请查看Cats-effect 和异步 IO 细节


尝试

  val readWriteName: IO[String] = for {
    _     <- IO(println("write your name: "))
    name  <- readLn
    _     <- IO(println(s"Hello, $name"))
    _     <- name match {
      case "stop" => IO(println(s"Buy Buy"))
      case _      =>  readWriteName
    }
  } yield name

推荐阅读