Invariant super class of Alternative and Decidable
Nobody has claimed this yet.
- Dominant language
- Scala
- Stars
- 5.5k
- Forks
- 1.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 5
Description
This ties into #1935, but also #2400 and #1932.
I think we could do a lot better with the Alternative hierarchy and the Decidable PR shows, it might need some binary breaking changes.
Ideally we could replicate the *Monoidal hierarchy, but using sum types instead. Then at the end we'd have InvariantSemiringal and have Alternative and Decidable extend from that.
Some code I came up with (names are not final by any means):
// Invariant hierarchy
@typeclass
trait InvariantAddSemigroupal[F[_]] {
def invariant: Invariant[F]
def sum[A, B](fa: F[A], fb: F[B]): F[Either[A, B]]
}
@typeclass
trait InvariantAddMonoidal[F[_]] extends InvariantAddSemigroupal[F] {
def empty[A]: F[A]
}
@typeclass
trait InvariantSemiringal[F[_]] extends InvariantAddMonoidal[F] with InvariantMonoidal[F]
// Covariant hierarchy
@typeclass
trait SemigroupK[F[_]] extends InvariantAddSemigroupal[F] {
def combineK[A](x: F[A], y: F[A]): F[A]
def functor: Functor[F]
override def invariant: Invariant[F] = functor
override def sum[A, B](fa: F[A], fb: F[B]): F[Either[A, B]] =
combineK(functor.map(fa)(Left(_)), functor.map(fb)(Right(_)))
}
@typeclass
trait MonoidK[F[_]] extends SemigroupK[F] with InvariantAddMonoidal[F]
@typeclass
trait Alternative[F] extends MonoidK[F] with InvariantSemiringal[F]
// Contravariant hierarchy
@typeclass
trait ContravariantAddSemigroupal[F[_]] extends InvariantAddSemigroupal[F] {
def contravariant: Contravariant[F]
override def invariant: Invariant[F] = contravariant
}
@typeclass
trait ContravariantAddMonoidal[F[_]] extends ContravariantAddSemigroupal[F] with InvariantAddMonoidal[F]
@typeclass
trait Decidable[F] extends ContravariantAddMonoidal[F] with InvariantSemiringal[F]
I've also written about this quite a bit in this blog post: https://typelevel.org/blog/2018/11/02/semirings.html
I made a funky looking diagram real quick:

As to why this is useful, I think this offers a really great API for codec combinators when working with e.g. circe, scodec or recently skunk.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the existing Alternative and Decidable hierarchies, then review related issues #1935, #2400, and #1932 and the linked semirings blog post. Done would require an agreed hierarchy design, including names and binary-compatibility decisions; the issue does not identify files or tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100