Laws for testing type class instances in the Cats functional programming library for Scala
npx @tessl/cli install tessl/maven-org-typelevel--cats-laws_native0-5_2-13@2.12.00
# Cats Laws
1
2
A comprehensive library providing laws for testing type class instances in the Cats functional programming library for Scala. The cats-laws package ensures that type class implementations satisfy the mathematical laws they should uphold, providing property-based testing capabilities for functional programming abstractions.
3
4
## Package Information
5
6
- **Package Name**: cats-laws
7
- **Package Type**: maven
8
- **Language**: Scala
9
- **Installation**: `libraryDependencies += "org.typelevel" %% "cats-laws" % "2.13.0"`
10
11
## Core Imports
12
13
```scala
14
import cats.laws._
15
import cats.laws.discipline._
16
```
17
18
For ScalaCheck testing:
19
20
```scala
21
import cats.laws.discipline.FunctorTests
22
import org.scalacheck.Prop._
23
```
24
25
## Basic Usage
26
27
```scala
28
import cats.laws.discipline.MonadTests
29
import cats.syntax.all._
30
import org.scalacheck.{Arbitrary, Gen}
31
import org.scalatest.funsuite.AnyFunSuite
32
import org.scalatestplus.scalacheck.Checkers
33
34
class OptionLawTests extends AnyFunSuite with Checkers {
35
36
// Test that Option satisfies Monad laws
37
checkAll("Option.MonadLaws", MonadTests[Option].monad[Int, Int, String])
38
39
// Test that List satisfies Functor laws
40
checkAll("List.FunctorLaws", FunctorTests[List].functor[Int, Int, String])
41
}
42
```
43
44
## Architecture
45
46
The cats-laws library is organized into two main packages:
47
48
- **`cats.laws`** - Contains trait definitions for mathematical laws that type classes must satisfy
49
- **`cats.laws.discipline`** - Contains ScalaCheck-based test implementations for property-based testing
50
51
Each type class in Cats has corresponding Laws and Tests classes following a consistent pattern:
52
1. `*Laws[F[_]]` traits define the mathematical properties as methods returning `IsEq[T]`
53
2. `*Tests[F[_]]` traits provide ScalaCheck property tests via `RuleSet` objects
54
3. Companion objects provide convenient `apply` methods for instantiation
55
56
## Capabilities
57
58
### Core Laws and Testing
59
60
The foundational laws for basic type class hierarchies including Functor, Applicative, and Monad.
61
62
```scala { .api }
63
trait FunctorLaws[F[_]] extends InvariantLaws[F] {
64
implicit def F: Functor[F]
65
def covariantIdentity[A](fa: F[A]): IsEq[F[A]]
66
def covariantComposition[A, B, C](fa: F[A], f: A => B, g: B => C): IsEq[F[C]]
67
}
68
69
trait MonadLaws[F[_]] extends ApplicativeLaws[F] with FlatMapLaws[F] {
70
def monadLeftIdentity[A, B](a: A, f: A => F[B]): IsEq[F[B]]
71
def monadRightIdentity[A](fa: F[A]): IsEq[F[A]]
72
}
73
```
74
75
[Core Laws and Testing](./core-laws.md)
76
77
### Alternative and MonoidK Laws
78
79
Laws for alternative operations and monoid structures on type constructors.
80
81
```scala { .api }
82
trait AlternativeLaws[F[_]] extends NonEmptyAlternativeLaws[F] with MonoidKLaws[F] {
83
def alternativeRightAbsorption[A, B](ff: F[A => B]): IsEq[F[B]]
84
def alternativeLeftDistributivity[A](fa: F[A], fa2: F[A], f: A => A): IsEq[F[A]]
85
}
86
87
trait MonoidKLaws[F[_]] extends SemigroupKLaws[F] {
88
implicit def F: MonoidK[F]
89
}
90
```
91
92
[Alternative and MonoidK Laws](./alternative-laws.md)
93
94
### Traversal Laws
95
96
Laws for traverse and foldable operations that work with applicative effects.
97
98
```scala { .api }
99
trait TraverseLaws[F[_]] extends FunctorLaws[F] with FoldableLaws[F] {
100
implicit override def F: Traverse[F]
101
}
102
103
trait FoldableLaws[F[_]] {
104
implicit def F: Foldable[F]
105
}
106
```
107
108
[Traversal Laws](./traversal-laws.md)
109
110
### Bifunctor Laws
111
112
Laws for bifunctors and related binary type constructors.
113
114
```scala { .api }
115
trait BifunctorLaws[F[_, _]] {
116
implicit def F: Bifunctor[F]
117
def bifunctorIdentity[A, B](fab: F[A, B]): IsEq[F[A, B]]
118
def bifunctorComposition[A, B, C, D](fab: F[A, B], f: A => C, g: B => D, f2: C => C, g2: D => D): IsEq[F[C, D]]
119
}
120
```
121
122
[Bifunctor Laws](./bifunctor-laws.md)
123
124
### Comonad Laws
125
126
Laws for comonads and coflatMap operations.
127
128
```scala { .api }
129
trait ComonadLaws[F[_]] extends CoflatMapLaws[F] {
130
implicit override def F: Comonad[F]
131
}
132
133
trait CoflatMapLaws[F[_]] extends FunctorLaws[F] {
134
implicit override def F: CoflatMap[F]
135
}
136
```
137
138
[Comonad Laws](./comonad-laws.md)
139
140
### Category Theory Laws
141
142
Laws for categories, arrows, and compositional structures.
143
144
```scala { .api }
145
trait CategoryLaws[F[_, _]] extends ComposeLaws[F] {
146
implicit override def F: Category[F]
147
}
148
149
trait ArrowLaws[F[_, _]] extends CategoryLaws[F] with StrongLaws[F] {
150
implicit override def F: Arrow[F]
151
}
152
```
153
154
[Category Theory Laws](./category-laws.md)
155
156
### Commutative Laws
157
158
Laws for commutative versions of applicative functors and monads.
159
160
```scala { .api }
161
trait CommutativeMonadLaws[F[_]] extends CommutativeApplicativeLaws[F] with CommutativeFlatMapLaws[F] with MonadLaws[F]
162
163
trait CommutativeApplicativeLaws[F[_]] extends CommutativeApplyLaws[F] with ApplicativeLaws[F]
164
```
165
166
[Commutative Laws](./commutative-laws.md)
167
168
### Error Handling Laws
169
170
Laws for error handling with ApplicativeError and MonadError.
171
172
```scala { .api }
173
trait ApplicativeErrorLaws[F[_], E] extends ApplicativeLaws[F] {
174
implicit override def F: ApplicativeError[F, E]
175
}
176
177
trait MonadErrorLaws[F[_], E] extends ApplicativeErrorLaws[F, E] with MonadLaws[F] {
178
implicit override def F: MonadError[F, E]
179
}
180
```
181
182
[Error Handling Laws](./error-laws.md)
183
184
### Parallel and Align Laws
185
186
Laws for parallel operations and alignment of functors.
187
188
```scala { .api }
189
trait ParallelLaws[M[_], F[_]] {
190
def parallel: Parallel.Aux[M, F]
191
}
192
193
trait AlignLaws[F[_]] extends FunctorLaws[F] {
194
implicit override def F: Align[F]
195
def alignAssociativity[A, B, C](fa: F[A], fb: F[B], fc: F[C]): IsEq[F[Ior[Ior[A, B], C]]]
196
}
197
```
198
199
[Parallel and Align Laws](./parallel-laws.md)
200
201
### Testing Utilities
202
203
Utility classes and objects for property-based testing and law verification.
204
205
```scala { .api }
206
trait ExhaustiveCheck[A] {
207
def allValues: List[A]
208
}
209
210
case class MiniInt(toInt: Int) extends AnyVal {
211
def +(other: MiniInt): MiniInt
212
def *(other: MiniInt): MiniInt
213
}
214
```
215
216
[Testing Utilities](./testing-utilities.md)
217
218
## Key Types
219
220
```scala { .api }
221
// Core law verification type
222
type IsEq[A] = cats.kernel.laws.IsEq[A]
223
224
// Implicit class for creating IsEq instances
225
implicit final class IsEqArrow[A](private val lhs: A) extends AnyVal {
226
def <->(rhs: A): IsEq[A]
227
}
228
229
// ScalaCheck rule sets for organized testing
230
trait RuleSet {
231
def name: String
232
def bases: Seq[(String, RuleSet)]
233
def props: Seq[(String, Prop)]
234
}
235
```