typelevel / typelevel/cats-mtl

Are cats.mtl.Handle[F[_], E] and cats.ApplicativeError[F[_], E] the same abstraction?

Open
#646 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Scala
Stars
307
Forks
66
Avg merge
6h 23m
Merged PRs (30d)
2

Description

Are cats.mtl.Handle[F[_], E] and cats.ApplicativeError[F[_], E] the same abstraction?

I can't see a meaningful difference between them. Handle includes code to derive itself from ApplicativeError. The reverse derivation also seems possible. So they appear isomorphic.

Which suggests the machinery for submarine error propagation could equally be supported for ApplicativeError, potentially reaching the wider audience of Cats users.

It also seems confusing, to me at least, to have two isomorphic type-classes in the same ecosystem.

There is also cats.MonadError, a subclass of ApplicativeError which is often more useful in practice, because it permits sequencing operations with flatMap - a common requirement of application code.

MonadError[F, E] suffices to express fallible-but-othewise-pure computations and neatly abstracts across concrete effects Either, and the more powerful cats.effect.IO (with submarines to permit non-Throwable error types). So the ability to derive Handle+Monad=>MonadError seems valuable.

given [F[_]: Monad as m, E](using h: Handle[F, E]): MonadError[F, E] = new MonadError:
  def pure[A](x: A): F[A] = h.applicative.pure(x)
  def handleErrorWith[A](fa: F[A])(f: E => F[A]): F[A] = h.handleWith(fa)(f)
  def raiseError[A](e: E): F[A] = h.raise(e)
  def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] = m.flatMap(fa)(f)
  def tailRecM[A, B](a: A)(f: A => F[Either[A, B]]): F[B] = m.tailRecM(a)(f)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read core/src/main/scala/cats/mtl/Handle.scala, cats/ApplicativeError.scala, and cats/MonadError.scala, then review the issue discussion and existing derivation machinery. Done requires a maintainer-approved decision on whether these abstractions should be unified or related differently, followed by the agreed implementation or documentation change.

Written by the indexing model from the issue text.

Assessment

Tech stack
scala
Domain
backend-api-design
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.