scalaz效果的简单控制流程

时间:2013-04-13 16:45:38

标签: scala scalaz scalaz7

拿一下这段简单的代码:

var line = "";

do {
  println("Please enter a non-empty line: ")
  line = readLine()
} while (line.isEmpty())

println("You entered a non-empty line: " + line)

这绝对不是特别优雅,尤其是line的不幸范围 - 但是,我觉得这很简单。

现在尝试将其直接转换为scalaz效果,我想出了:

def nonEmptyLine: IO[String] = for {
   _ <- putStrLn("Please enter a non-empty line:")
   line <- readLn
   r <- if (line.isEmpty()) nonEmptyLine else IO(line)
}  yield r


(for {
  line <- nonEmptyLine
  _ <- putStrLn("You entered a non-empty line: " + line)
} yield ()).unsafePerformIO

这让我觉得我错过了什么,因为这根本不是一种改善?我缺少一些更高阶的控制流程吗?

1 个答案:

答案 0 :(得分:3)

您可以跳过for符号并使用组合器*>>>=将所有内容组合在一起,从而使这个(至少可以说是)更漂亮:

import scalaz._, Scalaz._, effect._, IO._

val prompt = putStrLn("Please enter a non-empty line:")

def report(line: String) = putStrLn("You entered a non-empty line: " + line)

def nonEmptyLine: IO[String] = prompt *> readLn >>= (
  (line: String) => if (line.isEmpty) nonEmptyLine else line.point[IO]
)

然后:

scala> (nonEmptyLine >>= report).unsafePerformIO
Please enter a non-empty line:
You entered a non-empty line: This is a test.

但是,一般情况下,我不确定您是否应该期望使用scalaz.effect编写的代码比简单的命令式解决方案更简洁或更易于阅读。