Synchronous tasks

You can asynchronously define the preceding computation as follows:

def taskLight(prefix: String): IO[Nothing] =  Monad[IO].tailRecM(0) { i => for {    _ <- IO { println(s"${Thread.currentThread.getName}; $prefix: $i") }    _ <- IO.sleep(1 second)  } yield Left(i + 1) }

Notice that this method is defined similarly to the previous task. However, we no longer block the thread. Instead, we are using a built-in IO primitive called sleep. sleep is a non-blocking primitive, meaning that it does not block the underlying thread. That is, it is a description of the sleep operation. Remember, all of the computations happening defined in terms of IO are descriptions of computations and not computations themselves. So, you can define a sleep ...

Get Mastering Functional Programming now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.