FlatMap and for understanding with IO Monad

Looking at an example of IO Monad from Functional Programming in 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((d + 32).toString)
} yield ()

I decided to rewrite converterusing flatMap.

def converterFlatMap: IO[Unit] = PrintLine("enter a temperate in degrees F").
     flatMap(x => ReadLine.map(_.toDouble)).
       flatMap(y => PrintLine((y + 32).toString))

When I replaced the latter flatMapwith map, I did not see the result of printing readLine on the console.

C flatMap:

enter a temperate in degrees 
37.0

C map:

enter a temperate in degrees

Why? Also, how is signature ( IO[Unit]) still the same as mapor flatMap?

Here is the monad IOfrom this book.

  sealed trait IO[A] { self =>
    def run: A
    def map[B](f: A => B): IO[B] =
      new IO[B] { def run = f(self.run) }
    def flatMap[B](f: A => IO[B]): IO[B] =
      new IO[B] { def run = f(self.run).run }
  }
+3
source share
1 answer

I think Scala will convert IO [IO [Unit]] to IO [Unit] in the second case. Try to run both options in the Scala console and not specify the type for def converterFlatMap: IO[Unit], and you will see the difference.

, , IO: IO [IO [T]], run IO, IO [IO [T]], PrintLine ReadLine.

flatMap IO, IO[T], T A IO, .

P.S.: , . , , , :

PrintLine("enter a temperate in degrees F").flatMap { case _ =>
    ReadLine.map(_.toDouble).flatMap { case d =>
        PrintLine((d + 32).toString).map { case _ => ()}
    }
}

, flatMaps/maps .

P.P.S: for flatMap, map. , Scala "return", ,
(, return (3) IO [Int], run 3.),
for (x <- a; y <- b) yield y
a.flatMap(x => b.flatMap( y => return(y))),
b.flatMap( y => return(y)) , b.map(y => y) Scala .

+5

All Articles