2014-02-10 38 views
1

寻找一个IO Monad例如,从Functional Programming in Scala,我创建了一个SBT项目来测试IO.scala评估`readLine`在SBT

def ReadLine: IO[String] = IO { readLine } 
def PrintLine(msg: String): IO[Unit] = IO { println(msg) } 

def converter: IO[Unit] = for { 
    _ <- PrintLine("Enter a temperature in degrees fahrenheit: ") 
    d <- ReadLine.map(_.toDouble) 
    _ <- PrintLine(fahrenheitToCelsius(d).toString) 
} yield() 

但是,当我运行console从SBT与REPL访问上面的类,我想:

scala> val echo = Util.ReadLine.flatMap(Util.PrintLine) 
echo: common.I01.IO[Unit] = [email protected] 

我期待被提示输入在文本输入(通过readLine),但我看到,我的理解,简单的匿名函数/类。

我该如何测试上面的代码?

回答

1

ReadLine上调用flatMap只会产生一个未解释的值IO[Unit]。在某些时候,你必须调用IO#run(或scalaz IO#unsafePerformIO)使副作用发生

为了保持参照透明度,一般的想法是建立一个IO[A](其中A通常Unit),并在“最外面的“部分,请在该值上调用run - 例如,从应用程序的主入口点。尽管取决于您所使用的环境 - 例如某种形式的框架或容器,这并不总是容易/可能的。

因为参照透明度的损失通常被认为是一个非常严重的缺点,所以通常推迟运行IO值尽可能长。因此,在宇宙结束时评估IO是很常见的。

在这种情况下,Universe的结尾是REPL会话,因此请尝试从REPL调用echo.run

+0

谢谢。当你说“宇宙的末日是REPL会议”时,你能否详细说明一下?在几年前扫描Haskell书籍之前,我曾听过宇宙术语。 –

+0

我刚刚清理了一下术语,并添加了“宇宙末日”短语的基本原理。让我知道如果这是明确的。 – mpilquist