Convert Figma logo to code with AI

typelevel logocats

Lightweight, modular, and extensible library for functional programming.

5,233
1,190
5,233
249

Top Related Projects

4,670

Principled Functional Programming in Scala

4,064

ZIO — A type-safe, composable library for async and concurrent programming in Scala

The pure asynchronous runtime for Scala

1,926

Asynchronous, Reactive Programming for Scala and Scala.js.

2,354

Compositional, streaming I/O library for Scala

Quick Overview

Cats is a library for functional programming in Scala. It provides a set of type classes, data types, and functions that enable developers to write more expressive, composable, and safer code using functional programming principles. Cats is designed to be lightweight and modular, allowing users to import only the features they need.

Pros

  • Extensive set of functional programming abstractions and utilities
  • Well-documented with a large and active community
  • Modular design allows for selective imports and reduced overhead
  • Seamless integration with other Scala libraries and frameworks

Cons

  • Steep learning curve for developers new to functional programming
  • Can lead to increased code complexity if not used judiciously
  • Some performance overhead compared to imperative code in certain scenarios
  • May require additional mental effort to understand and maintain for teams unfamiliar with FP concepts

Code Examples

Example 1: Using Option with Cats

import cats.implicits._

val maybeInt: Option[Int] = Some(5)
val maybeString: Option[String] = Some("Hello")

val result: Option[String] = (maybeInt, maybeString).mapN { (i, s) =>
  s"$s, $i!"
}
// result: Option[String] = Some("Hello, 5!")

This example demonstrates how to use Cats' mapN function to combine multiple Option values.

Example 2: Working with Either for error handling

import cats.implicits._

def divide(a: Int, b: Int): Either[String, Int] =
  if (b == 0) Left("Division by zero")
  else Right(a / b)

val result = for {
  x <- divide(10, 2)
  y <- divide(x, 0)
} yield y

// result: Either[String, Int] = Left("Division by zero")

This example shows how to use Either for error handling and composition using for-comprehensions.

Example 3: Using Validated for accumulating errors

import cats.data.Validated
import cats.implicits._

case class User(name: String, age: Int)

def validateName(name: String): Validated[List[String], String] =
  if (name.isEmpty) Validated.invalid(List("Name cannot be empty"))
  else Validated.valid(name)

def validateAge(age: Int): Validated[List[String], Int] =
  if (age < 0) Validated.invalid(List("Age must be non-negative"))
  else Validated.valid(age)

def createUser(name: String, age: Int): Validated[List[String], User] =
  (validateName(name), validateAge(age)).mapN(User)

val result = createUser("", -5)
// result: Validated[List[String], User] = Invalid(List("Name cannot be empty", "Age must be non-negative"))

This example demonstrates how to use Validated to accumulate multiple validation errors.

Getting Started

To start using Cats in your Scala project, add the following dependency to your build.sbt file:

libraryDependencies += "org.typelevel" %% "cats-core" % "2.9.0"

Then, import the necessary Cats modules in your Scala files:

import cats._
import cats.implicits._

You can now start using Cats' functional programming abstractions in your code.

Competitor Comparisons

4,670

Principled Functional Programming in Scala

Pros of Scalaz

  • Longer history and more mature codebase
  • Wider range of advanced functional programming concepts
  • Stricter adherence to category theory principles

Cons of Scalaz

  • Steeper learning curve for beginners
  • Less frequent updates and releases
  • Smaller community and ecosystem compared to Cats

Code Comparison

Scalaz:

import scalaz._
import Scalaz._

val result = List(1, 2, 3).foldMap(identity)

Cats:

import cats._
import cats.implicits._

val result = List(1, 2, 3).foldMap(identity)

Both libraries provide similar functionality for common operations, but Scalaz often includes more advanced features and abstractions. Cats focuses on providing a more approachable and modular API, making it easier for newcomers to adopt functional programming concepts in Scala.

Scalaz tends to have more specialized types and type classes, while Cats aims for a balance between power and simplicity. The choice between the two often depends on the project's requirements, team expertise, and personal preferences.

Overall, Cats has gained more popularity in recent years due to its more accessible approach and active community, while Scalaz remains a powerful option for advanced functional programming in Scala.

4,064

ZIO — A type-safe, composable library for async and concurrent programming in Scala

Pros of ZIO

  • Simpler learning curve and more intuitive API for beginners
  • Built-in concurrency and resource management
  • Comprehensive ecosystem with integrated libraries for common tasks

Cons of ZIO

  • Less flexible type classes compared to Cats
  • Smaller community and fewer third-party libraries
  • Potential lock-in to the ZIO ecosystem

Code Comparison

ZIO example:

import zio._

val program = for {
  _ <- Console.printLine("Enter your name:")
  name <- Console.readLine
  _ <- Console.printLine(s"Hello, $name!")
} yield ()

Cats example:

import cats.effect.IO

val program = for {
  _ <- IO.println("Enter your name:")
  name <- IO.readLine
  _ <- IO.println(s"Hello, $name!")
} yield ()

Both ZIO and Cats are powerful functional programming libraries for Scala. ZIO offers a more opinionated and integrated approach, while Cats provides a more flexible and modular set of abstractions. ZIO may be easier for newcomers to functional programming, but Cats offers greater flexibility and a larger ecosystem of third-party libraries. The choice between them often depends on project requirements and team preferences.

The pure asynchronous runtime for Scala

Pros of cats-effect

  • Provides a complete IO monad implementation for effectful computations
  • Offers concurrency primitives and abstractions for building concurrent applications
  • Includes resource management utilities for safe handling of resources

Cons of cats-effect

  • Steeper learning curve due to more advanced concepts and abstractions
  • Larger dependency footprint compared to the core cats library
  • May introduce unnecessary complexity for projects that don't require advanced effect handling

Code Comparison

cats:

import cats.Functor

def map[F[_]: Functor, A, B](fa: F[A])(f: A => B): F[B] =
  Functor[F].map(fa)(f)

cats-effect:

import cats.effect.{IO, Resource}

val resource: Resource[IO, Connection] = Resource.make(
  acquire = IO(openConnection())
)(release = conn => IO(conn.close()))

Summary

cats is a lightweight, general-purpose functional programming library, while cats-effect builds upon cats to provide a comprehensive toolkit for effectful programming. cats-effect is ideal for applications requiring advanced concurrency, resource management, and IO operations, but may be overkill for simpler projects where cats alone suffices.

1,926

Asynchronous, Reactive Programming for Scala and Scala.js.

Pros of Monix

  • Focuses on reactive and asynchronous programming, offering specialized tools for these domains
  • Provides a more comprehensive set of concurrency primitives and utilities
  • Includes its own implementation of Observable, similar to RxJava

Cons of Monix

  • Less widely adopted compared to Cats, potentially leading to a smaller community and ecosystem
  • More specialized focus may make it less suitable for general-purpose functional programming tasks
  • Steeper learning curve due to its more extensive API and specialized concepts

Code Comparison

Cats (Effect) example:

import cats.effect.IO

val program: IO[Unit] = for {
  _ <- IO.println("Hello")
  _ <- IO.println("World")
} yield ()

Monix example:

import monix.eval.Task

val program: Task[Unit] = for {
  _ <- Task.eval(println("Hello"))
  _ <- Task.eval(println("World"))
} yield ()

Summary

Cats is a more general-purpose functional programming library, while Monix specializes in reactive and asynchronous programming. Cats has a larger community and ecosystem, making it a better choice for general FP tasks. Monix, on the other hand, offers more specialized tools for concurrent and reactive programming, which can be beneficial for specific use cases. The choice between the two depends on the project requirements and the developer's familiarity with each library's concepts.

2,354

Compositional, streaming I/O library for Scala

Pros of fs2

  • Specialized for streaming and I/O operations
  • Provides powerful abstractions for working with infinite data streams
  • Integrates well with other functional libraries in the Typelevel ecosystem

Cons of fs2

  • Steeper learning curve for developers new to functional programming
  • More focused scope compared to Cats' broader applicability
  • May introduce additional complexity for simple use cases

Code Comparison

fs2:

import fs2.{Stream, text}
import cats.effect.IO

val stream: Stream[IO, String] = Stream.emit("Hello, World!")
  .through(text.utf8.encode)
  .through(text.base64.encode)

Cats:

import cats.implicits._
import cats.effect.IO

val result: IO[String] = IO("Hello, World!")
  .map(_.getBytes("UTF-8"))
  .map(java.util.Base64.getEncoder.encodeToString)

Summary

fs2 excels in stream processing and I/O operations, offering powerful abstractions for working with infinite data streams. It integrates well with other Typelevel libraries but has a steeper learning curve. Cats, on the other hand, provides a broader set of functional programming abstractions applicable to various domains. While fs2 is more specialized, Cats offers a more general-purpose toolkit for functional programming in Scala.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Cats

Cats graphic

cats-core Scala version support Continuous Integration Financial Contributors on Open Collective Discord

Overview

Cats is a library which provides abstractions for functional programming in the Scala programming language.

Scala supports both object-oriented and functional programming, and this is reflected in the hybrid approach of the standard library. Cats strives to provide functional programming abstractions that are core, binary compatible, modular, approachable and efficient. A broader goal of Cats is to provide a foundation for an ecosystem of pure, typeful libraries to support functional programming in Scala applications.

For more detail about Cats' motivations, go here.

Why "cats"?

The name is a playful shortening of the word category, from "category theory".

Regardless, you do not need to know anything about category theory to use Cats.

Contributors

Code Contributors

This project exists thanks to all the people who contribute. We welcome contributions to Cats and would love for you to help build Cats. See our contributor guide for more information about how you can get involved as a developer. If you are looking for something to start with, here is a beginner friendly list.

Financial Contributors

Become a financial contributor and help us sustain our community. Donations directly support office hours for maintainers, better documentation and strategic initiatives.

Platinum Sponsors

Platinum sponsorship starts at $950 USD/month.

Gold Sponsors

Gold Sponsorship starts at $420 USD/month.

Silver Sponsors

Silver Sponsorship starts at $180 USD/month.

Backers

Become a Backer with a recurring donation of just $5 USD/month.

Other contributors

We thankfully accept one-time and recurring contributions as well.

Getting Started

Cats is available for Scala.js and Scala Native, as well as the standard JVM runtime.

Cats relies on improved type inference via the fix for SI-2712, which is not enabled by default. For Scala 2.12 you should add the following to your build.sbt:

scalacOptions += "-Ypartial-unification"

(Partial unification is on by default since Scala 2.13, the compiler no longer accepts -Ypartial-unification)

And then create the Cats dependency, by adding the following to your build.sbt:

libraryDependencies += "org.typelevel" %% "cats-core" % "2.9.0"

This will pull in the cats-core module. If you require some other functionality, you can pick-and-choose from amongst these modules (used in place of "cats-core"):

  • cats-kernel: Small set of basic type classes (required).
  • cats-core: Most core type classes and functionality (required).
  • cats-laws: Laws for testing type class instances.
  • cats-free: Free structures such as the free monad, and supporting type classes.
  • cats-testkit: lib for writing tests for type class instances using laws.
  • algebra: Type classes to represent algebraic structures.
  • alleycats-core: Cats instances and classes which are not lawful.

There are several other Cats modules that are in separate repos so that they can maintain independent release cycles.

  • cats-effect: standard IO type together with Sync, Async and Effect type classes
  • cats-mtl: transformer typeclasses for Cats' Monads, Applicatives and Functors.
  • mouse: a small companion to Cats that provides convenient syntax (aka extension methods)
  • kittens: automatic type class instance derivation for Cats and generic utility functions
  • cats-tagless: Utilities for tagless final encoded algebras
  • cats-collections: Data structures which facilitate pure functional programming
  • cats-testkit-scalatest: Cats testkit integration with Scalatest

Past release notes for Cats are available in CHANGES.md.

Documentation

Links:

  1. Website: typelevel.org/cats/
  2. ScalaDoc: typelevel.org/cats/api/
  3. Type classes: typelevel.org/cats/typeclasses.html
  4. Data types: typelevel.org/cats/datatypes.html
  5. Algebra overview: typelevel.org/cats/algebra.html
  6. Glossary: typelevel.org/cats/nomenclature.html
  7. Resources for Learners: typelevel.org/cats/resources_for_learners.html
  8. FAQ: typelevel.org/cats/faq.html
  9. The Typelevel Ecosystem: typelevel.org/cats/typelevelEcosystem.html

Community

Discussion around Cats is currently happening on GitHub issues, PR pages, and Discord:

The Typelevel Discord has #cats and #cats-dev channels, as well as community channels such as #beginners. Please join us!

People are expected to follow the Scala Code of Conduct when discussing Cats on GitHub, Discord, or other venues.

We hope that our community will be respectful, helpful, and kind. If you find yourself embroiled in a situation that becomes heated, or that fails to live up to our expectations, you should disengage and contact one of the project maintainers in private. We hope to avoid letting minor aggressions and misunderstandings escalate into larger problems.

If you are being harassed, please contact one of us immediately so that we can support you.

Binary compatibility and versioning

After 1.0.0 release, we decided to use MAJOR.MINOR.PATCH Semantic Versioning 2.0.0 going forward, which is different from the EPOCH.MAJOR.MINOR scheme common among Java and Scala libraries (including the Scala lang).

Cats strives to provide a solid and stable foundation for an ecosystem of FP libraries. Thus, we treat backward binary compatibility maintenance with a high priority. In semantic versioning, backward breaking change is ONLY allowed between MAJOR versions. We will maintain backward binary compatibility between PATCH AND MINOR versions. For example, when we release Cats 1.1.0, it will be backward binary compatible with the previous 1.0.x versions. I.E. the new JAR will be a drop-in replacement for the old one. This is critical when your application has a diamond dependency on Cats - depending on two or more libraries that all depend on Cats. If one library upgrades to the new 1.1.0 Cats before the other one does, your application still runs thanks to this backward binary compatibility.

Also worth noting is that according to semantic versioning, MINOR version Y (x.Y.z | x > 0) MUST be incremented if new, backwards compatible functionality is introduced to the public API. It MUST be incremented if any public API functionality is marked as deprecated.

Any binary breaking changes will require a MAJOR version bump, which we will be very cautious about. We will also consider using organization and package name for major versioning in the future. But that decision is yet to be made.

Adopters

A (non-exhaustive) list of companies that use Cats in production is featured in ADOPTERS.md. Don't see yours? You can add it in a PR! And if you can, consider supporting us.

Maintainers

The current maintainers (people who can merge pull requests) are:

Retired committers include:

We are currently following a practice of requiring at least two sign-offs to merge code PRs (and for large or contentious issues we may wait for more). For typos, documentation improvements or minor build fix we relax this to a single sign-off. More detail in the process document.

Copyright and License

All code is available to you under the MIT license, available at http://opensource.org/licenses/mit-license.php and also in the COPYING file. The design is informed by many other projects, in particular Scalaz.

Copyright the maintainers, 2015-2024.