【问题标题】:Combining Scalaz IO monad with Stream for simple echo program using takeWhile method使用 takeWhile 方法将 Scalaz IO monad 与 Stream 结合用于简单的 echo 程序
【发布时间】:2015-09-19 17:28:39
【问题描述】:

我正在使用 Scalaz IO Monad 和 Stream 在 spoj.com 上寻找“生命、宇宙和一切”问题的解决方案。 问题是从输入到输出重写小数字,并在读入数字 42 后停止处理输入。 我创建了以下类:

import scalaz._, effect._

def ReadInt: IO[Int] = IO {
    readInt
}
def PrintInt(i: Int): IO[Unit] = IO {
    println(i)
}
def EchoInt: IO[Int] = {
    for {
        i <- ReadInt
        _ <- PrintInt(i)
    } yield (i)
}

永无止境的循环按预期工作:

scala> import Scalaz._
scala> Stream.continually(EchoInt).sequence.unsafePerformIO
12
22
32
42
52

但是,当我希望它在数字 42 上完成时,它也没有完成:

scala> Stream.continually(EchoInt).sequence.map(_.takeWhile(_ != 42)).unsafePerformIO
12
22
32
42
52

我知道这段代码毕竟应该打印 42(与问题陈述相反),但我想简化示例代码。

我在哪里犯错了?

【问题讨论】:

  • 我的 build.sbt 文件:scalaVersion := "2.11.7" libraryDependencies ++= Seq{ "org.scalaz" %% "scalaz-core" % "7.1.4" "org.scalaz " %% "scalaz 效果" % "7.1.4" }

标签: io monads scalaz io-monad


【解决方案1】:

Stream.continually(EchoInt).sequence 无限次重复EchoInt,所以你的程序基本上是一个无限循环。

您要做的是将某种break 放入循环中,这将分析每次迭代的输入并在输入等于42 时停止循环。函数式编程中没有break(因为没有循环,只有递归),所以你根本不继续递归:

import scalaz.syntax.monad._

...

def echoInts: IO[Unit] = {
  for {
    i <- EchoInt
    _ <- echoInts.whenM(i != 42) // Break if i == 42
  } yield ()
}

echoInts.unsafePerformIO()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    • 2015-03-12
    相关资源
    最近更新 更多