I am reading chapter 13.2.1 and came across the example that can handle IO input and get rid of side effect in the meantime:
object IO extends Monad[IO] {
def unit[A](a: => A): IO[A] = new IO[A] { def run = a }
def flatMap[A,B](fa: IO[A])(f: A => IO[B]) = fa flatMap f
def apply[A](a: => A): IO[A] = unit(a)
}
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 ()
I have couple of questions regarding this piece of code:
- In the
unit
function, what doesdef run = a
really do? - In the
ReadLine
function, what doesIO { readLine }
really do? Will it really execute theprintln
function or just return an IO type? - What does
_
in the for comprehension mean (_ <- PrintLine("Enter a temperature in degrees Fahrenheit: ")
) ? - Why it removes the IO side effects? I saw these functions still interact with inputs and outputs.