使用takeWhile方法将Scalaz IO monad与Stream结合用于简单回波程序

使用takeWhile方法将Scalaz IO monad与Stream结合用于简单回波程序,io,monads,scalaz,io-monad,Io,Monads,Scalaz,Io Monad,我正在spoj.com上使用Scalaz IO Monad和Stream为“生命、宇宙和一切”问题寻找解决方案。 问题是从输入到输出重写小数字,并在读取数字42后停止处理输入。 我创建了以下类: import scalaz._, effect._ def ReadInt: IO[Int] = IO { readInt } def PrintInt(i: Int): IO[Unit] = IO { println(i) } def EchoInt: IO[Int] = {

我正在spoj.com上使用Scalaz IO Monad和Stream为“生命、宇宙和一切”问题寻找解决方案。 问题是从输入到输出重写小数字,并在读取数字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)
}
但是,当我希望它在42号上结束时,它不会也结束:

scala> Stream.continually(EchoInt).sequence.map(_.takeWhile(_ != 42)).unsafePerformIO
12
22
32
42
52
我知道这段代码毕竟应该打印42条(与问题陈述相反),但我想简化示例代码

我哪里出错了?

连续流(EchoInt)。序列
重复
EchoInt
无限次,因此您的程序基本上是一个无限循环

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

import scalaz.syntax.monad._

...

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

echoInts.unsafePerformIO()
导入scalaz.syntax.monad_
...
def回声输入:IO[单位]={
为了{

我的build.sbt文件:scalaVersion:=“2.11.7”libraryDependencies++=Seq{“org.scalaz”%%“scalaz核心”%%“7.1.4”“org.scalaz”%%“scalaz效果”%%“7.1.4”}
import scalaz.syntax.monad._

...

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

echoInts.unsafePerformIO()