Skip to content

Instantly share code, notes, and snippets.

@valencik
Created December 29, 2022 01:09
Show Gist options
  • Save valencik/6283849c33b52841136da36675c0fe3c to your computer and use it in GitHub Desktop.
Save valencik/6283849c33b52841136da36675c0fe3c to your computer and use it in GitHub Desktop.
A very simplified view of the cats typeclass hierarchy building to IO

Cats

The Typelevel ecosystem of libraries for functional programming in Scala provides several fundamental type classes for representing the capabilities of different computations.

Functor

Effect: Transforming the value inside an effect by mapping over it

📚 Functor docs

🧬 Functor code

🧮 Functor API

trait Functor[F[_]] {

  def map[A, B](fa: F[A])(f: A => B): F[B]
}

Applicative

Effect: Putting a value into an effect

📚 applicative docs

🧬 applicative code

🧮 applicative API

trait Applicative[F[_]] extends Functor[F] {

  def ap[A, B](ff: F[A => B])(fa: F[A]): F[B]

  def pure[A](x: A): F[A]
}

Monad

Effect: Composing multiple effectful computations together sequentially, such that each is dependent on the previous

📚 Monad docs

🧬 Monad code

🧮 Monad API

trait Monad[F[_]] extends Applicative[F] {

    def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
}

MonadError

Effect: Raising and handling errors

📚 MonadError docs

🧬 MonadError code

🧮 MonadError API

trait MonadError[F[_], E] with Monad[F] {

   def ensure[A](fa: F[A])(error: => E)(predicate: A => Boolean): F[A]

   def rethrow[A, EE <: E](fa: F[Either[EE, A]]): F[A]
}

Defer

Effect: Delay the creation of a value

🧬 Defer code

🧮 Defer API

  • Defer is a type class that shows the ability to defer creation inside of the type constructor F
trait Defer[F[_]] {

  def defer[A](fa: => F[A]): F[A]
}

Cats Effect

MonadCancel

Effect: Resource safety, guarantee finalizers will run on cancelation

📚 MonadCancel docs

🧬 MonadCancel code

🧮 MonadCancel API

trait MonadCancel[F[_], E] extends MonadError[F, E] {

  def bracket[A, B](acquire: F[A])(use: A => F[B])(release: A => F[Unit]): F[B]

  def uncancelable[A](body: Poll[F] => F[A]): F[A]

  def canceled: F[Unit]
}

Spawn

Effect: Parallel evaluation

📚 Spawn docs

🧬 GenSpawn code

🧮 GenSpawn API

  • Provides Fiber
    • Best used to implement the Parallel typeclass
trait GenSpawn[F[_], E] extends MonadCancel[F, E] {

  def start[A](fa: F[A]): F[Fiber[F, E, A]]

  def never[A]: F[A]

  def cede: F[Unit]
}
  • Spawn is defined as type Spawn[F[_]] = GenSpawn[F, Throwable]

Concurrent

Effect: State sharing between parallel processes

📚 Concurrent docs

🧬 GenConcurrent code

🧮 GenConcurrent API

trait GenConcurrent[F[_], E] extends GenSpawn[F, E] {

  def ref[A](a: A): F[Ref[F, A]]

  def deferred[A]: F[Deferred[F, A]]

  def memoize[A](fa: F[A]): F[F[A]]
}
  • Concurrent is defined as type Concurrent[F[_]] = GenConcurrent[F, Throwable]

Clock

Effect: Measuring time

📚 Clock docs

🧬 Clock code

🧮 Clock API

trait Clock[F[_]] {

  def monotonic: F[FiniteDuration]

  def realTime: F[FiniteDuration]
}

Temporal

Effect: Interactions with time, include current time and sleeping

📚 Temporal docs

🧬 GenTemporal code

🧮 GenTemporal API

trait GenTemporal[F[_], E] extends GenConcurrent[F, E] with Clock[F] {

  def sleep(time: Duration): F[Unit]
}
  • Temporal is defined as type Temporal[F[_]] = GenTemporal[F, Throwable]

Sync

Effect: Safe capture of side-effects which return values

📚 Sync docs

🧬 Sync code

🧮 Sync API

trait Sync[F[_]] extends MonadCancel[F, Throwable] with Clock[F] with Defer[F] {

  def suspend[A](hint: Sync.Type)(thunk: => A): F[A]
}

Async

Effect: Safe capture of side-effects which invoke a callback

📚 Async docs

🧬 Async code

🧮 Async API

trait Async[F[_]] extends Sync[F] with Temporal[F] {

  def async[A](k: (Either[Throwable, A] => Unit) => F[Option[F[Unit]]]): F[A]

  def async_[A](k: (Either[Throwable, A] => Unit) => Unit): F[A]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment