Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding IO monad

I'm trying to understand asynchronous computation by cats.effect.IO examples and got some misunderstanding. The unsafe method unsafeRunAsync seems like running the underlying effect asynchronously (I expected that some ContextShift to be provided). But the method looks simply like this:

final def unsafeRunAsync(cb: Either[Throwable, A] => Unit): Unit =
  IORunLoop.start(this, cb)

Neither ContextShift nor ExecutionContext is provided. Here is the very simple example:

object TestIo extends App {
  println(s"Main thread = ${Thread.currentThread().getName}")
  val io = IO {
    println(s"Effect thread = ${Thread.currentThread().getName}")
    Thread.sleep(1000)
  }
  io.unsafeRunAsync(_ => println(s"Callback thread = ${Thread.currentThread().getName}"))
  println(s"Finished")
}

The output is

Main thread = main
Effect thread = main
Callback thread = main
Finished

As you can see everything here is run in the main thread synchronously. Can you please explain unsafeRunAsync? To me it seems the same as unsafeRunSync.

like image 362
St.Antario Avatar asked Nov 14 '18 14:11

St.Antario


People also ask

How does the IO monad work?

The I/O monad contains primitives which build composite actions, a process similar to joining statements in sequential order using `;' in other languages. Thus the monad serves as the glue which binds together the actions in a program.

What is monad used for?

A monad is an algebraic structure in category theory, and in Haskell it is used to describe computations as sequences of steps, and to handle side effects such as state and IO. Monads are abstract, and they have many useful concrete instances. Monads provide a way to structure a program.

What is IO monad Scala?

The IO monad provides a straightforward way of embedding imperative programming with I/O effects in a pure program while preserving referential transparency. It clearly separates effectful code—code that needs to have some effect on the outside world—from the rest of our program.

What does IO mean in Haskell?

IO is the way how Haskell differentiates between code that is referentially transparent and code that is not. IO a is the type of an IO action that returns an a . You can think of an IO action as a piece of code with some effect on the real world that waits to get executed.


1 Answers

About

Neither ContextShift nor ExecutionContext is provided.

There is a context switch in cats.effect.IO

See this blog: https://www.jaspervanzandbeek.com/scala/cats-io-monad/

Here an example from there:

def blockingOperation(): String = {
  // Read from file
  ...
}

val result: IO[String] = for {
  _ <- IO.shift(executionContextForBlockingOperations)
  result <- IO { blockingOperation() }
  _ <- IO.shift(mainExecutionContext)
} yield result
like image 108
pme Avatar answered Oct 20 '22 19:10

pme