Frage

Looking at an IO Monad example from Functional Programming in Scala, I created an SBT project to test out IO.scala:

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 ()

But, when I run console from SBT to access the above class with REPL, I tried:

scala> val echo = Util.ReadLine.flatMap(Util.PrintLine)
echo: common.I01.IO[Unit] = common.I01$IO$$anon$2@71c6b580

I'm expecting to be prompted for typing in text (via readLine), but I see, as I understand, simply an anonymous function/class.

How can I test out the above code?

War es hilfreich?

Lösung

Calling flatMap on ReadLine just produces an IO[Unit] value that has not been interpreted. At some point, you have to call IO#run (or IO#unsafePerformIO in scalaz) to make the side effects happen

To preserve referential transparency, the general idea is to build up an IO[A] (where A is typically Unit) and at the "outermost" part of your program, call run on the value -- for example, from the main entry point of the application. That's not always easy/possible though depending on the environment you are running in -- e.g., some form of framework or container.

Because loss of referential transparency is generally considered a pretty serious disadvantage, it is common to defer running of the IO value as long as possible. Hence, it is common to say that IO is evaluated at the end of the universe.

In this case, the end of the universe is the REPL session, so try calling echo.run from the REPL.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top