Alleycats provides type class instances and classes which are not lawful but may be useful in some scenarios
npx @tessl/cli install tessl/maven-org-typelevel--alleycats-core_2-13@2.13.0Alleycats Core provides functional programming type class instances and abstractions that extend Cats but don't satisfy the strict mathematical laws required by Cats core. It offers pragmatic solutions for real-world functional programming scenarios while maintaining the same modular structure and cross-platform compatibility.
libraryDependencies += "org.typelevel" %% "alleycats-core" % "2.13.0"import alleycats._ // Core type classes
import alleycats.std.all._ // All standard library instances
import alleycats.syntax.all._ // All syntax extensionsSelective imports:
import alleycats.{Pure, EmptyK, Extract} // Specific type classes
import alleycats.std.map._ // Map instances only
import alleycats.syntax.extract._ // Extract syntax onlyimport alleycats._
import alleycats.std.all._
import alleycats.syntax.all._
import cats.syntax.all._
// Using Pure for lifting values
def liftToOption[A](value: A): Option[A] = Pure[Option].pure(value)
// Using EmptyK for creating empty collections
val emptyMap: Map[String, Int] = EmptyK[Map[String, *]].empty[Int]
val emptyList: List[String] = EmptyK[List].empty[String]
// Using Extract for getting values from contexts
import scala.util.Try
val tryValue = Try(42)
// Note: Extract[Try] requires alleycats instance
// val extracted = tryValue.extract // Gets the value or throws
// Using Empty with standard types
import cats.implicits._
val emptyString = Empty[String].empty // From Monoid instanceAlleycats Core is organized into several key modules:
Essential type classes that provide useful abstractions for functional programming.
// Pure - lift values into contexts
Pure[F].pure[A](a: A): F[A]
// EmptyK - create empty higher-kinded types
EmptyK[F].empty[A]: F[A]
// Extract - extract values from contexts
Extract[F].extract[A](fa: F[A]): A
// Empty - types with empty values
Empty[A].empty: A
Empty[A].isEmpty(a: A): Boolean
// Zero and One - types with zero/one values
Zero[A].zero: A
One[A].one: A
// ConsK - cons elements to front of structures
ConsK[F].cons[A](hd: A, tl: F[A]): F[A]Specialized type classes for identity-based operations.
// ReferentialEq - referential equality
ReferentialEq[A <: AnyRef]: Eq[A] // Uses eq for comparison
// SystemIdentityHash - identity-based hashing
SystemIdentityHash[A <: AnyRef]: Hash[A] // Uses System.identityHashCodeType class instances for Scala standard library types that don't satisfy strict categorical laws.
// Map instances
Traverse[Map[K, *]]
TraverseFilter[Map[K, *]]
EmptyK[Map[K, *]]
// Set instances (non-lawful but useful)
Monad[Set] & Alternative[Set] & Traverse[Set] & TraverseFilter[Set]
// List instances
EmptyK[List]
ConsK[List]
// Option instances
EmptyK[Option]
// Try instances (non-lawful Monad)
Bimonad[Try]
// Future instances
Pure[Future]
// Iterable instances
Traverse[Iterable]
TraverseFilter[Iterable]Convenient method extensions for type classes.
// Extract syntax
fa.extract // Extract value from context
// Empty syntax
a.isEmpty // Check if value is empty
a.nonEmpty // Check if value is non-empty
// Foldable syntax
fa.foreach(f) // Side-effecting foreach// Core type classes
trait Pure[F[_]] {
def pure[A](a: A): F[A]
}
trait EmptyK[F[_]] {
def empty[A]: F[A]
def synthesize[A]: Empty[F[A]]
}
trait Extract[F[_]] {
def extract[A](fa: F[A]): A
}
trait Empty[A] {
def empty: A
def isEmpty(a: A)(implicit ev: Eq[A]): Boolean
def nonEmpty(a: A)(implicit ev: Eq[A]): Boolean
}
trait Zero[A] {
def zero: A
def isZero(a: A)(implicit ev: Eq[A]): Boolean
def nonZero(a: A)(implicit ev: Eq[A]): Boolean
}
trait One[A] {
def one: A
def isOne(a: A)(implicit ev: Eq[A]): Boolean
def nonOne(a: A)(implicit ev: Eq[A]): Boolean
}
trait ConsK[F[_]] {
def cons[A](hd: A, tl: F[A]): F[A]
}
trait ReferentialEq[A <: AnyRef] extends Eq[A] {
def eqv(x: A, y: A): Boolean
}
trait SystemIdentityHash[A <: AnyRef] extends ReferentialEq[A] with Hash[A] {
override def hash(a: A): Int
}