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.00
# Cats Core
1
2
Cats 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.
3
4
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.
5
6
## Package Information
7
8
- **Package Name**: cats-core
9
- **Package Type**: maven
10
- **Language**: Scala
11
- **Organization**: org.typelevel
12
- **Installation**: `libraryDependencies += "org.typelevel" %% "cats-core" % "2.0.0"`
13
14
## Core Imports
15
16
```scala
17
import cats._
18
import cats.data._
19
import cats.implicits._
20
```
21
22
For specific type classes:
23
24
```scala
25
import cats.{Functor, Applicative, Monad}
26
import cats.syntax.functor._
27
import cats.syntax.applicative._
28
```
29
30
For data types:
31
32
```scala
33
import cats.data.{Chain, NonEmptyList, Validated, EitherT, OptionT}
34
```
35
36
## Basic Usage
37
38
```scala
39
import cats._
40
import cats.data._
41
import cats.implicits._
42
43
// Using Functor with Option
44
val option: Option[Int] = Some(42)
45
val doubled = option.map(_ * 2) // Some(84)
46
47
// Using Applicative to combine values
48
val name: Option[String] = Some("John")
49
val age: Option[Int] = Some(25)
50
val person = (name, age).mapN((n, a) => s"$n is $a years old") // Some("John is 25 years old")
51
52
// Using Monad for sequencing operations
53
def safeDivide(x: Int, y: Int): Option[Int] =
54
if (y != 0) Some(x / y) else None
55
56
val result = for {
57
a <- Some(20)
58
b <- Some(4)
59
c <- safeDivide(a, b)
60
} yield c // Some(5)
61
62
// Using Validated for accumulating errors
63
val validName = "John".valid[String]
64
val invalidAge = "not a number".invalid[Int]
65
val validatedPerson = (validName, invalidAge).mapN((n, a) => s"$n is $a years old")
66
// Invalid(not a number)
67
68
// Using Chain for efficient concatenation
69
val chain1 = Chain(1, 2, 3)
70
val chain2 = Chain(4, 5, 6)
71
val combined = chain1 ++ chain2 // Chain(1, 2, 3, 4, 5, 6)
72
```
73
74
## Architecture
75
76
Cats is built around several key components:
77
78
- **Type Classes**: Abstract interfaces that define behavior (Functor, Monad, Applicative, etc.)
79
- **Data Types**: Concrete types that implement type class instances (Chain, NonEmptyList, Validated, etc.)
80
- **Monad Transformers**: Composable wrappers that combine effects (OptionT, EitherT, StateT, etc.)
81
- **Syntax Extensions**: Implicit conversions that add methods to types via `cats.implicits._`
82
- **Type Class Instances**: Implementations of type classes for standard Scala types
83
- **Arrow Types**: Category-theoretic constructions for composable functions
84
85
## Capabilities
86
87
### Type Classes
88
89
Core functional programming abstractions including Functor, Applicative, Monad, and many others. These provide the foundation for composable, lawful functional programming.
90
91
```scala { .api }
92
trait Functor[F[_]] {
93
def map[A, B](fa: F[A])(f: A => B): F[B]
94
}
95
96
trait Applicative[F[_]] extends Functor[F] {
97
def pure[A](x: A): F[A]
98
def ap[A, B](ff: F[A => B])(fa: F[A]): F[B]
99
}
100
101
trait Monad[F[_]] extends Applicative[F] {
102
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
103
def tailRecM[A, B](a: A)(f: A => F[Either[A, B]]): F[B]
104
}
105
```
106
107
[Type Classes](./type-classes.md)
108
109
### Data Types
110
111
Essential data structures for functional programming including Chain, NonEmptyList, Validated, and others that provide type-safe alternatives to standard collections.
112
113
```scala { .api }
114
sealed abstract class Chain[+A] {
115
def append[A2 >: A](other: Chain[A2]): Chain[A2]
116
def prepend[A2 >: A](item: A2): Chain[A2]
117
def toList: List[A]
118
}
119
120
sealed abstract class NonEmptyList[+A] {
121
def head: A
122
def tail: List[A]
123
def map[B](f: A => B): NonEmptyList[B]
124
}
125
126
sealed abstract class Validated[+E, +A] {
127
def isValid: Boolean
128
def isInvalid: Boolean
129
def fold[B](fe: E => B, fa: A => B): B
130
}
131
```
132
133
[Data Types](./data-types.md)
134
135
### Monad Transformers
136
137
Composable wrappers that combine multiple effects, allowing you to work with nested monadic contexts like `F[Option[A]]` or `F[Either[E, A]]`.
138
139
```scala { .api }
140
final case class OptionT[F[_], A](value: F[Option[A]]) {
141
def map[B](f: A => B)(implicit F: Functor[F]): OptionT[F, B]
142
def flatMap[B](f: A => OptionT[F, B])(implicit F: Monad[F]): OptionT[F, B]
143
def getOrElse[B >: A](default: => B)(implicit F: Functor[F]): F[B]
144
}
145
146
final case class EitherT[F[_], A, B](value: F[Either[A, B]]) {
147
def map[C](f: B => C)(implicit F: Functor[F]): EitherT[F, A, C]
148
def flatMap[C](f: B => EitherT[F, A, C])(implicit F: Monad[F]): EitherT[F, A, C]
149
def leftMap[C](f: A => C)(implicit F: Functor[F]): EitherT[F, C, B]
150
}
151
```
152
153
[Monad Transformers](./monad-transformers.md)
154
155
### Arrow Types
156
157
Category theory-based abstractions for composable functions and natural transformations between type constructors.
158
159
```scala { .api }
160
trait Category[F[_, _]] {
161
def id[A]: F[A, A]
162
def compose[A, B, C](f: F[B, C], g: F[A, B]): F[A, C]
163
}
164
165
trait Arrow[F[_, _]] extends Category[F] {
166
def lift[A, B](f: A => B): F[A, B]
167
def first[A, B, C](fa: F[A, B]): F[(A, C), (B, C)]
168
}
169
170
trait FunctionK[F[_], G[_]] {
171
def apply[A](fa: F[A]): G[A]
172
}
173
```
174
175
[Arrow Types](./arrow-types.md)
176
177
### Syntax Extensions
178
179
Implicit conversions and extension methods that provide a fluent API for working with type classes and data types.
180
181
```scala { .api }
182
implicit class FunctorOps[F[_], A](private val fa: F[A]) extends AnyVal {
183
def map[B](f: A => B)(implicit F: Functor[F]): F[B] = F.map(fa)(f)
184
def void(implicit F: Functor[F]): F[Unit] = F.void(fa)
185
def as[B](b: B)(implicit F: Functor[F]): F[B] = F.as(fa, b)
186
}
187
188
implicit class ApplicativeOps[F[_], A](private val fa: F[A]) extends AnyVal {
189
def product[B](fb: F[B])(implicit F: Apply[F]): F[(A, B)] = F.product(fa, fb)
190
def *>[B](fb: F[B])(implicit F: Apply[F]): F[B] = F.productR(fa)(fb)
191
def <*[B](fb: F[B])(implicit F: Apply[F]): F[A] = F.productL(fa)(fb)
192
}
193
```
194
195
[Syntax Extensions](./syntax-extensions.md)
196
197
## Key Type Aliases
198
199
```scala { .api }
200
type Id[A] = A // Identity type
201
type Endo[A] = A => A // Endomorphism
202
type ~>[F[_], G[_]] = FunctionK[F, G] // Natural transformation
203
type :<:[F[_], G[_]] = InjectK[F, G] // Type constructor injection
204
205
// Kernel type aliases from cats-kernel
206
type Eq[A] = cats.kernel.Eq[A]
207
type Order[A] = cats.kernel.Order[A]
208
type PartialOrder[A] = cats.kernel.PartialOrder[A]
209
type Semigroup[A] = cats.kernel.Semigroup[A]
210
type Monoid[A] = cats.kernel.Monoid[A]
211
type Group[A] = cats.kernel.Group[A]
212
```
213
214
## Error Handling
215
216
Cats provides several approaches to error handling:
217
218
- **MonadError**: For monads that can raise and handle errors
219
- **ApplicativeError**: For applicatives that can raise and handle errors
220
- **Validated**: For accumulating errors without short-circuiting
221
- **Either**: Standard Scala Either with additional Cats syntax
222
223
Common error handling patterns are documented in the respective capability sections.