Cats is a library which provides abstractions for functional programming in the Scala programming language.
npx @tessl/cli install tessl/maven-org-typelevel--cats-core_2-11@2.0.0Cats is a library which provides abstractions for functional programming in the Scala programming language. The cats-core module contains the core type classes and data structures for category theory abstractions including Functor, Applicative, Monad, and many others.
Cats-core serves as the foundation for functional programming in Scala ecosystems, offering zero-dependency type classes that can be extended and composed to build more complex functional programming patterns and domain-specific libraries.
libraryDependencies += "org.typelevel" %% "cats-core" % "2.0.0"import cats._
import cats.data._
import cats.implicits._For specific type classes:
import cats.{Functor, Applicative, Monad}
import cats.syntax.functor._
import cats.syntax.applicative._For data types:
import cats.data.{Chain, NonEmptyList, Validated, EitherT, OptionT}import cats._
import cats.data._
import cats.implicits._
// Using Functor with Option
val option: Option[Int] = Some(42)
val doubled = option.map(_ * 2) // Some(84)
// Using Applicative to combine values
val name: Option[String] = Some("John")
val age: Option[Int] = Some(25)
val person = (name, age).mapN((n, a) => s"$n is $a years old") // Some("John is 25 years old")
// Using Monad for sequencing operations
def safeDivide(x: Int, y: Int): Option[Int] =
if (y != 0) Some(x / y) else None
val result = for {
a <- Some(20)
b <- Some(4)
c <- safeDivide(a, b)
} yield c // Some(5)
// Using Validated for accumulating errors
val validName = "John".valid[String]
val invalidAge = "not a number".invalid[Int]
val validatedPerson = (validName, invalidAge).mapN((n, a) => s"$n is $a years old")
// Invalid(not a number)
// Using Chain for efficient concatenation
val chain1 = Chain(1, 2, 3)
val chain2 = Chain(4, 5, 6)
val combined = chain1 ++ chain2 // Chain(1, 2, 3, 4, 5, 6)Cats is built around several key components:
cats.implicits._Core functional programming abstractions including Functor, Applicative, Monad, and many others. These provide the foundation for composable, lawful functional programming.
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
trait Applicative[F[_]] extends Functor[F] {
def pure[A](x: A): F[A]
def ap[A, B](ff: F[A => B])(fa: F[A]): F[B]
}
trait Monad[F[_]] extends Applicative[F] {
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
def tailRecM[A, B](a: A)(f: A => F[Either[A, B]]): F[B]
}Essential data structures for functional programming including Chain, NonEmptyList, Validated, and others that provide type-safe alternatives to standard collections.
sealed abstract class Chain[+A] {
def append[A2 >: A](other: Chain[A2]): Chain[A2]
def prepend[A2 >: A](item: A2): Chain[A2]
def toList: List[A]
}
sealed abstract class NonEmptyList[+A] {
def head: A
def tail: List[A]
def map[B](f: A => B): NonEmptyList[B]
}
sealed abstract class Validated[+E, +A] {
def isValid: Boolean
def isInvalid: Boolean
def fold[B](fe: E => B, fa: A => B): B
}Composable wrappers that combine multiple effects, allowing you to work with nested monadic contexts like F[Option[A]] or F[Either[E, A]].
final case class OptionT[F[_], A](value: F[Option[A]]) {
def map[B](f: A => B)(implicit F: Functor[F]): OptionT[F, B]
def flatMap[B](f: A => OptionT[F, B])(implicit F: Monad[F]): OptionT[F, B]
def getOrElse[B >: A](default: => B)(implicit F: Functor[F]): F[B]
}
final case class EitherT[F[_], A, B](value: F[Either[A, B]]) {
def map[C](f: B => C)(implicit F: Functor[F]): EitherT[F, A, C]
def flatMap[C](f: B => EitherT[F, A, C])(implicit F: Monad[F]): EitherT[F, A, C]
def leftMap[C](f: A => C)(implicit F: Functor[F]): EitherT[F, C, B]
}Category theory-based abstractions for composable functions and natural transformations between type constructors.
trait Category[F[_, _]] {
def id[A]: F[A, A]
def compose[A, B, C](f: F[B, C], g: F[A, B]): F[A, C]
}
trait Arrow[F[_, _]] extends Category[F] {
def lift[A, B](f: A => B): F[A, B]
def first[A, B, C](fa: F[A, B]): F[(A, C), (B, C)]
}
trait FunctionK[F[_], G[_]] {
def apply[A](fa: F[A]): G[A]
}Implicit conversions and extension methods that provide a fluent API for working with type classes and data types.
implicit class FunctorOps[F[_], A](private val fa: F[A]) extends AnyVal {
def map[B](f: A => B)(implicit F: Functor[F]): F[B] = F.map(fa)(f)
def void(implicit F: Functor[F]): F[Unit] = F.void(fa)
def as[B](b: B)(implicit F: Functor[F]): F[B] = F.as(fa, b)
}
implicit class ApplicativeOps[F[_], A](private val fa: F[A]) extends AnyVal {
def product[B](fb: F[B])(implicit F: Apply[F]): F[(A, B)] = F.product(fa, fb)
def *>[B](fb: F[B])(implicit F: Apply[F]): F[B] = F.productR(fa)(fb)
def <*[B](fb: F[B])(implicit F: Apply[F]): F[A] = F.productL(fa)(fb)
}type Id[A] = A // Identity type
type Endo[A] = A => A // Endomorphism
type ~>[F[_], G[_]] = FunctionK[F, G] // Natural transformation
type :<:[F[_], G[_]] = InjectK[F, G] // Type constructor injection
// Kernel type aliases from cats-kernel
type Eq[A] = cats.kernel.Eq[A]
type Order[A] = cats.kernel.Order[A]
type PartialOrder[A] = cats.kernel.PartialOrder[A]
type Semigroup[A] = cats.kernel.Semigroup[A]
type Monoid[A] = cats.kernel.Monoid[A]
type Group[A] = cats.kernel.Group[A]Cats provides several approaches to error handling:
Common error handling patterns are documented in the respective capability sections.