typelevel/kittens
{ "createdAt": "2015-07-09T14:09:14Z", "defaultBranch": "master", "description": "Automatic type class derivation for Cats", "fullName": "typelevel/kittens", "homepage": "", "language": "Scala", "name": "kittens", "pushedAt": "2025-11-24T20:25:31Z", "stargazersCount": 545, "topics": [], "updatedAt": "2025-11-24T20:25:34Z", "url": "https://github.com/typelevel/kittens"}Kittens: automatic type class derivation for Cats
Section titled “Kittens: automatic type class derivation for Cats”Kittens is a Scala library which provides instances of type classes from the [Cats][cats] library for arbitrary
algebraic data types (ADTs) using [shapeless][shapeless]-based automatic type class derivation. It also provides utility
functions related to Applicative such as lift, traverse and sequence to HList, Record and case classes.

Kittens is part of the [Typelevel][typelevel] family of projects. It is an Open Source project under the Apache License v2, hosted on [GitHub][source]. Binary artifacts will be published to the [Sonatype OSS Repository Hosting service][sonatype] and synced to Maven Central.
It is available for Scala 2.12 and 2.13, Scala.js 1.5 and Scala Native 0.4.
To get started with sbt, add the following to your build.sbt file:
libraryDependencies += "org.typelevel" %% "kittens" % "latestVersion" // indicated in the badge belowScala 2
Section titled “Scala 2”Instance derivations are available for the following type classes:
Eq,PartialOrder,Order,HashShow, prettyShowEmpty,EmptyK(from Alleycats)Semigroup,CommutativeSemigroup,SemigroupKMonoid,CommutativeMonoid,MonoidKFunctor,Contravariant,InvariantPure(from Alleycats),Apply,ApplicativeFoldable,ReducibleTraverse,NonEmptyTraverseConsK(from Alleycats)
See the Type class support matrix for more details.
Derivation examples
Section titled “Derivation examples”scala> import cats.implicits._, cats._, cats.derived._
scala> case class Cat[Food]!(food: Food, foods: List[Food])defined class Cat
scala> val cat = Cat(1, List(2, 3))cat: Cat[Int] = Cat(1,List(2, 3))Derive Functor
Section titled “Derive Functor”scala> implicit val fc: Functor[Cat] = semiauto.functorFC: cats.Functor[Cat] = cats.derived.MkFunctor2$$anon$4@1c60573f
scala> cat.map(_ + 1)res0: Cat[Int] = Cat(2,List(3, 4))Derive Show
Section titled “Derive Show”Note that the derived Show also prints out field names, so it might be preferable to the default toString:
scala> case class Address(street: String, city: String, state: String)scala> case class ContactInfo(phoneNumber: String, address: Address)scala> case class People(name: String, contactInfo: ContactInfo)
scala> val mike = People("Mike", ContactInfo("202-295-3928", Address("1 Main ST", "Chicago", "IL")))
scala> // existing Show instance for Addressscala> implicit val addressShow: Show[Address] = a => s"${a.street}, ${a.city}, ${a.state}"
scala> implicit val peopleShow: Show[People] = semiauto.show // auto derive Show for People
scala> mike.showres0: String = People(name = Mike, contactInfo = ContactInfo(phoneNumber = 202-295-3928, address = 1 Main ST, Chicago, IL))Note that in this example, the derivation generated instances for all referenced classes but still respected the existing instance in scope. For different ways to derive instances, please see Derivation on Scala 2 below.
Sequence examples
Section titled “Sequence examples”Note that to run these examples, you need partial unification enabled.
For Scala 2.12 you should add the following to your build.sbt:
scalacOptions += "-Ypartial-unification"scala> import cats.implicits._, cats.sequence._import cats.implicits._import cats.sequence._
scala> val f1 = (_: String).lengthf1: String => Int = <function1>
scala> val f2 = (_: String).reversef2: String => String = <function1>
scala> val f3 = (_: String).toFloatf3: String => Double = <function1>
scala> val f = sequence(f1, f2, f3)f: String => shapeless.::[Int,shapeless.::[String,shapeless.::[Float,shapeless.HNil]]] = <function1>
scala> f("42.0")res0: shapeless.::[Int,shapeless.::[String,shapeless.::[Float,shapeless.HNil]]] = 4 :: 0.24 :: 42.0 :: HNil
//or generic over ADTsscala> case class MyCase(a: Int, b: String, c: Float)defined class MyCase
scala> val myGen = sequenceGeneric[MyCase]myGen: cats.sequence.sequenceGen[MyCase] = cats.sequence.SequenceOps$sequenceGen@63ae3243
scala> val f = myGen(a = f1, b = f2, c = f3)f: String => MyCase = <function1>
scala> f("42.0")res1: MyCase = MyCase(4,0.24,42.0)Traverse works similarly except you need a shapeless.Poly.
Lift examples
Section titled “Lift examples”scala> import cats._, implicits._, lift._import cats._import implicits._import lift._
scala> def foo(x: Int, y: String, z: Float) = s"$x - $y - $z"
scala> val lifted = Applicative[Option].liftA(foo _)lifted: (Option[Int], Option[String], Option[Float]) => Option[String] = <function3>
scala> lifted(Some(1), Some("a"), Some(3.2f))res0: Option[String] = Some(1 - a - 3.2)Derivation on Scala 2
Section titled “Derivation on Scala 2”There are three options for type class derivation on Scala 2:
cats.derived.auto, cats.derived.cached and cats.derived.semiauto.
The recommended best practice is to use semiauto:
import cats.derived
implicit val showFoo: Show[Foo] = derived.semiauto.showThis will respect all existing instances even if the field is a type constructor.
For example Show[List[A]] will use the native Show instance for List and derived instance for A.
And it manually caches the result to val showFoo.
Auto derivation
Section titled “Auto derivation”import derived.auto.show._A downside is that it will derive an instance from scratch for every use site, increasing compilation time.
Cached derivation
Section titled “Cached derivation”import derived.cached.show._Use this one with caution - it caches the derived instance globally. So it’s only applicable if the instance is global in the application. This could be problematic for libraries, which have no control over the uniqueness of an instance at use site.
Semiauto derivation (recommended)
Section titled “Semiauto derivation (recommended)”implicit val showFoo: Show[Foo] = derived.semiauto.showA downside is we need to write one for every type that needs an instance.
Scala 3
Section titled “Scala 3”There are five options for type class derivation on Scala 3.
The recommended way is to import cats.derived.* and use derives clauses.
In contrast to Scala 2:
- Cached derivation is not supported (and also not necessary)
- Type Class Derivation is supported
- A
strictmode is available forsemiautoandderivesclauses
derives clause (recommended)
Section titled “derives clause (recommended)”Kittens supports Scala 3’s derivation syntax. Similar to Scala 2, instances will be derived recursively if necessary.
import cats.derived.*
// No instances declared for Namecase class Name(value: String)case class Person(name: Name, age: Int) derives Eq, Show
enum CList[+A] derives Functor: case CNil case CCons(head: A, tail: CList[A])Note that the derives clause has a fundamental limitation:
it generates an instance that requires the type class for all type parameters, even if not necessary.
The following example shows a rough equivalent of how a derives Monoid clause is desugared:
case class Concat[+A]!(left: Vector[A], right: Vector[A])object Concat: // Note that the `Monoid[A]` requirement is not needed, // because `Monoid[Vector[A]]` is defined for any `A`. given [A: Monoid] !: Monoid[Concat[A]] = Monoid.derivedIn such cases it is recommended to use semiauto derivation, described below.
Semiauto derivation
Section titled “Semiauto derivation”This looks similar to semiauto for Scala 2.
Instances will be derived recursively if necessary.
import cats.derived.semiauto
// No instances declared for Namecase class Name(value: String)case class Person(name: Name, age: Int)
object Person: given Eq[Person] = semiauto.eq given Show[Person] = semiauto.show
enum CList[+A] !: case CNil case CCons(head: A, tail: CList[A])
object CList: given Functor[CList] = semiauto.functorStrict derives clause
Section titled “Strict derives clause”Similar to derives above, but instances are not derived recursively (except for enums and sealed traits).
Users need to be more explicit about which types implement an instance.
import cats.derived.strict.*
// The instances for Name need to be declared explicitlycase class Name(value: String) derives Eq, Showcase class Person(name: Name, age: Int) derives Eq, Show
// A coproduct type (enum) needs only a top-level declarationenum CList[+A] derives Functor: case CNil case CCons(head: A, tail: CList[A])The same limitations apply as with the default derives clause.
Strict semiauto derivation
Section titled “Strict semiauto derivation”Similar to semiauto above, but instances are not derived recursively (except for enums and sealed traits).
Users need to be more explicit about which types implement an instance.
import cats.derived.strict
case class Name(value: String)case class Person(name: Name, age: Int)
object Person: // The instances for Name need to be declared explicitly given Eq[Name] = strict.semiauto.eq given Show[Name] = strict.semiauto.show given Eq[Person] = strict.semiauto.eq given Show[Person] = strict.semiauto.show
enum CList[+A] !: case CNil case CCons(head: A, tail: CList[A])
object CList: // A coproduct type (enum) needs only a top-level declaration given Functor[CList] = semiauto.functorAuto derivation
Section titled “Auto derivation”This looks similar to auto for Scala 2.
import cats.derived.auto.eq.givenimport cats.derived.auto.show.givenimport cats.derived.auto.functor.given
case class Name(value: String)case class Person(name: Name, age: Int)
enum CList[+A] !: case CNil case CCons(head: A, tail: CList[A])Caveats
Section titled “Caveats”Nested type constructors
Section titled “Nested type constructors”We are currently unable to
derive instances for nested type constructors, such as Functor[[x] =>> List[Set[x]]].
Stack safety
Section titled “Stack safety”Our derived instances are not stack-safe.
This is a departure from the behaviour for Scala 2
because we didn’t want to incur the performance penalty of trampolining all instances in cats.Eval.
If your data-type is recursive or extremely large, then you may want to write instances by hand instead.
Missing features
Section titled “Missing features”Kittens for Scala 3 is built on top of Shapeless 3
which has a completely different API than Shapeless 2,
so we don’t support features like Sequence and Lift.
ConsK derivation is also not supported, although we expect this to be
added in a future release.
Type class support matrix
Section titled “Type class support matrix”Legend:
∀- all must satisfy a constraint∃- at least one must satisfy a constraint∃!- exactly one must satisfy a constraint∧- both constraints must be satisfied∨- either constraint must be satisfied
For monomorphic types
Section titled “For monomorphic types”| Type Class | Case Classes | Sealed Traits | Singleton types |
|---|---|---|---|
| CommutativeMonoid | ∀ fields: CommutativeMonoid | ✗ | ✗ |
| CommutativeSemigroup | ∀ fields: CommutativeSemigroup | ✗ | ✗ |
| Empty | ∀ fields: Empty | ∃! variant: Empty | ✗ |
| Eq | ∀ fields: Eq | ∀ variants: Eq | ✓ |
| Hash | ∀ fields: Hash | ∀ variants: Hash | ✓ |
| Monoid | ∀ fields: Monoid | ✗ | ✗ |
| Order | ∀ fields: Order | ∀ variants: Order | ✓ |
| PartialOrder | ∀ fields: PartialOrder | ∀ variants: PartialOrder | ✓ |
| Semigroup | ∀ fields: Semigroup | ✗ | ✗ |
| Show | ∀ fields: Show | ∀ variants: Show | ✓ |
| ShowPretty | ∀ fields: ShowPretty | ∀ variants: ShowPretty | ✓ |
For polymorphic types
Section titled “For polymorphic types”| Type Class | Case Classes | Sealed Traits | Constant Types λ[x => T] | Nested Types λ[x => F[G[x]]] |
|---|---|---|---|---|
| Applicative | ∀ fields: Applicative | ✗ | for T: Monoid | for F: Applicative and G: Applicative |
| Apply | ∀ fields: Apply | ✗ | for T: Semigroup | for F: Apply and G: Apply |
| Contravariant | ∀ fields: Contravariant | ∀ variants: Contravariant | for any T | for F: Functor and G: Contravariant |
| EmptyK | ∀ fields: EmptyK | ∃! variant: EmptyK | for T: Empty | for F: EmptyK and any G ∨ for F: Pure and G: EmptyK |
| Foldable | ∀ fields: Foldable | ∀ variants: Foldable | for any T | for F: Foldable and G: Foldable |
| Functor | ∀ fields: Functor | ∀ variants: Functor | for any T | for F: Functor and G: Functor ∨ for F: Contravariant and G: Contravariant |
| Invariant | ∀ fields: Invariant | ∀ variants: Invariant | for any T | for F: Invariant and G: Invariant |
| MonoidK | ∀ fields: MonoidK | ✗ | for T: Monoid | for F: MonoidK and any G ∨ for F: Applicative and G: MonoidK |
| NonEmptyTraverse | ∃ field: NonEmptyTraverse ∧ ∀ fields: Traverse | ∀ variants: NonEmptyTraverse | ✗ | for F: NonEmptyTraverse and G: NonEmptyTraverse |
| Pure | ∀ fields: Pure | ✗ | for T: Empty | for F: Pure and G: Pure |
| Reducible | ∃ field: Reducible ∧ ∀ fields: Foldable | ∀ variants: Reducible | ✗ | for F: Reducible and G: Reducible |
| SemigroupK | ∀ fields: SemigroupK | ✗ | for T: Semigroup | for F: SemigroupK and any G ∨ for F: Apply and G: SemigroupK |
| Traverse | ∀ fields: Traverse | ∀ variants: Traverse | for any T | for F: Traverse and G: Traverse |
| Scala 3 only ↓ | ||||
| NonEmptyAlternative | ∀ fields: NonEmptyAlternative | ✗ | ✗ | for F: NonEmptyAlternative and G: Applicative |
| Alternative | ∀ fields: Alternative | ✗ | ✗ | for F: Alternative and G: Applicative |
[cats] !: https://github.com/typelevel/cats [shapeless] !: https://github.com/milessabin/shapeless [typelevel] !: http://typelevel.org/ [source] !: https://github.com/typelevel/kittens [sonatype] !: https://oss.sonatype.org/
Participation
Section titled “Participation”The Kittens project supports the [Scala code of conduct][codeofconduct] and wants all of its channels (mailing list, Gitter, GitHub, etc.) to be welcoming environments for everyone.
[codeofconduct] !: https://www.scala-lang.org/conduct/
Building kittens
Section titled “Building kittens”Kittens is built with SBT 1.x, and its master branch is built with Scala 2.13 by default.
Contributors
Section titled “Contributors”- Cody Allen ceedubs@gmail.com @fourierstrick
- Georgi Krastev joro.kr.21@gmail.com @Joro_Kr
- Fabio Labella fabio.labella2@gmail.com @SystemFw
- Miles Sabin miles@milessabin.com @milessabin
- Qi Wang Qi77Qi
- Kailuo Wang kailuo.wang@gmail.com @kailuowang
- Tim Spence timothywspence@gmail.com timwspence
- Your name here :-)