kotlin-typeclasses runtime library¶
kotlin-typeclasses is the published runtime library for the one.wabbit.typeclass compiler-plugin family. Use it when you want Kotlin context parameters to behave like explicit, compile-time-checked typeclass evidence instead of manually threading dictionaries through every call.
It contains the public source and runtime surface used by normal Kotlin code:
- annotations such as
@Typeclass,@Instance,@Derive,@DeriveVia, and@DeriveEquiv - helper APIs such as
summon() - derivation metadata and derivation interfaces
- builtin proof interfaces such as
Same,Subtype,KnownType, andTypeId
There are no compiler internals in this module.
Repository Role¶
The typeclasses project family is split into four parts:
kotlin-typeclasses: this runtime librarykotlin-typeclasses-plugin: the Kotlin compiler plugin that performs resolution and code generationkotlin-typeclasses-gradle-plugin: the Gradle bridge that wires the compiler plugin into Kotlin buildskotlin-typeclasses-ij-plugin: the IntelliJ helper plugin for IDE-side compiler-plugin loading
Most consumers need this library together with the Gradle plugin.
The runtime library keeps the base project version, while the compiler plugin is published as a Kotlin-specific variant such as one.wabbit:kotlin-typeclasses-plugin:0.1.0-kotlin-2.3.10.
Status¶
This module is experimental and pre-1.0. Annotation names, generated metadata contracts, and proof APIs may still change between minor releases; source-level breaks are called out in the migration guide with mechanical upgrade notes.
Installation¶
- coordinates:
one.wabbit:kotlin-typeclasses:0.1.0
Most applications should add this dependency and apply the Gradle plugin from ../gradle-plugin/README.md. The runtime alone does not enable compiler-plugin resolution.
Public Surface¶
@Typeclass¶
Marks a supported typeclass head as participating in typeclass resolution.
Ordinary user-defined typeclasses should be interfaces annotated with @Typeclass.
There is also a narrow advanced path for subclassable abstract/open class heads with accessible zero-argument constructors. This exists mainly for compiler-owned surfaces such as Equiv and generated @DeriveVia adapter code; it is not the recommended shape for ordinary application typeclasses.
@Instance¶
Marks an object, function, or immutable property as a source of evidence.
The compiler plugin treats instance functions as rule-like declarations: no ordinary value parameters, optional context-parameter prerequisites, and a provided typeclass result.
Top-level instances are restricted: they must live in the same file as the typeclass head or one of the concrete provided classifiers in the target.
summon()¶
summon() is the user-facing way to ask for evidence from the current context:
context(value: T)
fun <T> summon(): T = value
On its own, that is just a context-parameter helper. The compiler plugin is what makes summon<Typeclass<...>>() participate in typeclass resolution.
Derivation Surface¶
The runtime owns the public derivation APIs.
Annotations:
@Derive@DeriveVia@DeriveEquiv
Metadata and interfaces:
ProductFieldMetadataProductTypeclassMetadataSumCaseMetadataSumTypeclassMetadataEnumEntryMetadataEnumTypeclassMetadataProductTypeclassDeriverTypeclassDeriverRecursiveTypeclassInstanceCell
These types are the public contract between user-authored typeclass companions and compiler-synthesized derived instances.
Builtin Proof APIs¶
The runtime also exposes proof-oriented typeclass interfaces that the compiler can materialize directly.
Current proof surfaces include:
SameNotSameSubtypeStrictSubtypeNullableNotNullableIsTypeclassInstanceSameTypeConstructorKnownTypeTypeIdEquivIso- optional builtin
KClass<T>evidence whenbuiltinKClassTypeclass=enabled - optional builtin
KSerializer<T>evidence whenbuiltinKSerializerTypeclass=enabled
The singleton carriers used to implement some of these proofs are internal details. End users program against the public proof interfaces.
Annotation Retention¶
The annotations in this module are intentionally not all the same:
- core compiler-consumed annotations such as
@Typeclass,@Instance, and@Deriveuse binary retention - tracing helpers such as
@DebugTypeclassResolutionuse source retention
That split reflects their roles:
- binary-retained annotations define semantic structure the compiler plugin needs to see across boundaries
- source-retained tracing annotations are compile-time controls, not part of runtime behavior
Quick Start¶
With the companion Gradle plugin:
plugins {
kotlin("jvm") version "2.3.10"
id("one.wabbit.typeclass")
}
dependencies {
implementation("one.wabbit:kotlin-typeclasses:0.1.0")
}
Then write source code using:
@Typeclassto declare a typeclass@Instanceto publish evidence@Deriveand related annotations to opt types into derivationsummon()or explicit context parameters to consume evidence
For detailed semantics of scope, derivation, proofs, and optional builtins, use the dedicated guides in ../docs/. Recommended order for new users: root quick start, user guide, typeclass model, derivation guide, then proof/builtin details.
Changelog¶
Breaking changes and mechanical upgrade notes live in ../docs/migration.md. Release publishing is managed from the repository root.
Support¶
Use ../docs/troubleshooting.md first for diagnostics, tracing, and known limits. Report bugs through the repository issue tracker, and use ../docs/development.md plus the legal docs under ../legal/ for contribution workflow.