Skip to content

Instantly share code, notes, and snippets.

@sentenza
Last active February 5, 2021 11:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sentenza/c1fed5856a2ade343d999321458003c4 to your computer and use it in GitHub Desktop.
Save sentenza/c1fed5856a2ade343d999321458003c4 to your computer and use it in GitHub Desktop.
Cats IO Monad vs Scala Future

From Scala Future to Cats Async?

We could try to use the Async type class to model the kind of effects that can be executed concurrently.

Async is a Monad that can describe asynchronous or synchronous computations that produce exactly one result.

The first data type that we can think of is cats.effect.IO but the key aspect to keep in mind is that either a Future or an IO might be synchronous/blocking operations.

IO.delay{ ... }
// same as
IO { ... }
  • IO { ... } does NOT make anything async (see IO.apply)
  • does NOT switch threads
  • creates simple IO values from synchronous side-effecting APIs
  • to force a "context shift" to another Execution Context we can take advantage of IO.shift

A very interesting discussion about this subject is this SO answer.

Future cannot be an Async

It's not possible to write an instance of Async for Future that has the right semantics, because Async extends Sync, and Sync requires a representation of a computation that can be run repeatedly, while Scala's futures begin running when they're defined and can't be re-run (eagerly evaluated).

Via SO answer (Async[Future])

F[_]: Monad from Future

Nevertheless, it's possible to get a generic HKT effect from Future:

import cats.effect.{Async, ContextShift]

def toF[F[_] : Async : ContextShift]: F[Result] =
  Async.fromFuture(Async[F].delay(functionReturningFuture(x)))

Via SO answer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment