使用 IO 打印输入 + 函数输出

Printing Input + Function Output with IO

我写了一个简单的函数(我打算)打印出 (1) 用户输入 + (2) 添加了 "foobar" 的输入:

import scalaz.effect.IO
import scalaz.effect.IO._

def simplePrint: (IO[Unit], IO[String]) = {
    val input = readLn
    val result = input.map(_ + "foobar")
    (input.flatMap(putStrLn), result)
}

def runExample: Unit = {
    val (in, result) = simplePrint
    println(">" + in.unsafePerformIO)
    println(result.unsafePerformIO)
}

进入REPL,我测试了一下

当我 运行 runExample 方法时,我输入了“555”,看到了输出,然后输入了“1234”。

scala> net.repl.Foo.runExample
555
>()
1234foobar

我原本希望输入:“555”,然后看到:

>555
555foobar

如何更改上述方法来执行此操作?

如果您不止一次调用 unsafePerformIO,您的程序可能有问题(理想情况下您会使用 SafeApp 而根本不调用它)。混合未跟踪的效果和 IO 也不必要地混乱。您希望对 所有 效果进行排序,如下所示:

scala> val action = putStrLn(">") >> readLn.map(_ + "foobar") >>= putStrLn
action: scalaz.effect.IO[Unit] = scalaz.effect.IOFunctions$$anon@5a2ab2df

scala> action.unsafePerformIO
>
555foobar

不过,这不会在键入时回显字符。我很确定我已经编写了代码来做到这一点(使用 getChar 和类似手卷 unfoldWhileM 的东西),如果您有兴趣,我可以稍后尝试挖掘它。