A type class and dependent type based generic programming library for Scala
npx @tessl/cli install tessl/maven-com-chuusai--shapeless_2-12@2.3.00
# Shapeless
1
2
Shapeless is a comprehensive generic programming library for Scala that enables type-safe, compile-time generic programming through type classes and dependent types. It provides powerful abstractions for working with heterogeneous lists, coproducts, generic representations, and automatic derivation of type class instances, allowing developers to eliminate boilerplate code while maintaining full type safety.
3
4
## Package Information
5
6
- **Package Name**: com.chuusai:shapeless_2.12
7
- **Package Type**: Maven (SBT)
8
- **Language**: Scala
9
- **Installation**: `libraryDependencies += "com.chuusai" %% "shapeless" % "2.3.13"`
10
11
## Core Imports
12
13
```scala
14
import shapeless._
15
```
16
17
For specific functionality:
18
19
```scala
20
import shapeless.{HList, ::, HNil, Generic, Coproduct, :+:, CNil}
21
import shapeless.ops.hlist._
22
import shapeless.ops.coproduct._
23
import shapeless.syntax.hlist._
24
import shapeless.syntax.coproduct._
25
import shapeless.labelled.FieldType
26
import shapeless.tag.@@
27
```
28
29
Common syntax extensions:
30
31
```scala
32
import shapeless.syntax.singleton._ // Narrow type literals
33
import shapeless.syntax.std.tuple._ // Tuple conversions
34
import shapeless.syntax.std.function._ // Function conversions
35
```
36
37
## Basic Usage
38
39
```scala
40
import shapeless._
41
42
// Define a case class
43
case class Person(name: String, age: Int, active: Boolean)
44
45
// Get generic representation
46
val gen = Generic[Person]
47
val person = Person("Alice", 30, true)
48
49
// Convert to HList
50
val hlist = gen.to(person) // String :: Int :: Boolean :: HNil
51
52
// Access elements by type
53
val name: String = hlist.select[String]
54
val age: Int = hlist.select[Int]
55
56
// Convert back to case class
57
val reconstructed = gen.from(hlist)
58
59
// Work with heterogeneous lists directly
60
val mixed: String :: Int :: Boolean :: HNil = "test" :: 42 :: true :: HNil
61
val length = mixed.length // Nat._3 (compile-time known)
62
val head = mixed.head // "test"
63
val tail = mixed.tail // Int :: Boolean :: HNil
64
```
65
66
## Architecture
67
68
Shapeless is built around several key architectural concepts:
69
70
- **Type-Level Programming**: Computations performed at compile-time using Scala's type system
71
- **Heterogeneous Data Structures**: Collections that can contain different types while preserving type information
72
- **Generic Representations**: Automatic conversion between user-defined types and generic forms
73
- **Dependent Types**: Types that depend on values, enabling precise type-level constraints
74
- **Automatic Derivation**: Compile-time generation of type class instances using macros
75
76
This design enables zero-runtime-cost abstractions and ensures that all type relationships are verified at compile time, making it impossible to access non-existent fields or perform invalid operations.
77
78
## Capabilities
79
80
### Core Type System and Infrastructure
81
82
Essential type operators, constraints, and dependent types that form the foundation of Shapeless. Includes identity types, logical operators, type inequalities, and basic utilities that underpin all other functionality.
83
84
```scala { .api }
85
type Id[+T] = T
86
type Const[C] = { type λ[T] = C }
87
88
// Type inequalities
89
trait =:!=[A, B] extends Serializable
90
trait <:!<[A, B] extends Serializable
91
92
// Logical type operators
93
type ¬[T] = T => Nothing
94
type ¬¬[T] = ¬[¬[T]]
95
type ∧[T, U] = T with U
96
type ∨[T, U] = ¬[¬[T] ∧ ¬[U]]
97
98
// Type-lambda helpers for context bounds
99
type |∨|[T, U] = { type λ[X] = ¬¬[X] <:< (T ∨ U) }
100
type |¬|[T] = { type λ[U] = U <:!< T }
101
102
// Quantifiers
103
type ∃[P[_]] = P[T] forSome { type T }
104
type ∀[P[_]] = ¬[∃[({ type λ[X] = ¬[P[X]]})#λ]]
105
106
// Dependent function types
107
trait DepFn0 { type Out; def apply(): Out }
108
trait DepFn1[T] { type Out; def apply(t: T): Out }
109
trait DepFn2[T, U] { type Out; def apply(t: T, u: U): Out }
110
111
// Macro-based cached implicit resolution
112
def cachedImplicit[T]: T = macro CachedImplicitMacros.cachedImplicitImpl[T]
113
```
114
115
### HLists and Heterogeneous Collections
116
117
Core heterogeneous data structures that can contain elements of different types while preserving complete type information at compile time. Provides extensive operations for construction, access, and transformation.
118
119
```scala { .api }
120
sealed trait HList
121
final case class ::[+H, +T <: HList](head: H, tail: T) extends HList
122
sealed trait HNil extends HList
123
124
// Construction and access
125
def apply[T](t: T): T :: HNil
126
def select[U]: U // Select element by type
127
def at[N <: Nat]: Out // Access by position
128
```
129
130
[HLists and Heterogeneous Collections](./hlist-collections.md)
131
132
### Coproducts and Union Types
133
134
Type-safe sum types representing "one of" relationships, enabling exhaustive pattern matching and safe union operations. The dual concept to HLists for modeling exclusive alternatives.
135
136
```scala { .api }
137
sealed trait Coproduct
138
sealed trait :+:[+H, +T <: Coproduct] extends Coproduct
139
final case class Inl[+H, +T <: Coproduct](head: H) extends (H :+: T)
140
final case class Inr[+H, +T <: Coproduct](tail: T) extends (H :+: T)
141
142
// Injection and selection
143
def inject[I]: I => Coproduct
144
def select[T]: Option[T]
145
```
146
147
[Coproducts and Union Types](./coproduct-unions.md)
148
149
### Generic Programming and Automatic Derivation
150
151
The core value proposition of Shapeless - automatic derivation of type class instances by converting between user-defined types and generic representations. Eliminates boilerplate code while maintaining type safety.
152
153
```scala { .api }
154
trait Generic[A] {
155
type Repr
156
def to(a: A): Repr
157
def from(repr: Repr): A
158
}
159
160
trait LabelledGeneric[A] {
161
type Repr
162
def to(a: A): Repr // Preserves field names as types
163
def from(repr: Repr): A
164
}
165
```
166
167
[Generic Programming and Automatic Derivation](./generic-derivation.md)
168
169
### Records and Named Field Access
170
171
Structured data access using field names rather than positions, providing a more user-friendly interface for working with case classes and other product types through symbolic field access.
172
173
```scala { .api }
174
type FieldType[K, +V] = V @@ KeyTag[K, V]
175
176
object field[K] extends FieldOf[K]
177
def selectDynamic(field: String): FieldType[K, V]
178
def updatedDynamic[V](field: String, value: V): Record
179
```
180
181
[Records and Named Field Access](./records-fields.md)
182
183
### Optics - Lenses and Prisms
184
185
Functional programming patterns for composable data access and transformation. Provides type-safe navigation and modification of nested data structures with automatic derivation.
186
187
```scala { .api }
188
case class Lens[S, A](get: S => A, set: S => A => S) {
189
def modify(s: S)(f: A => A): S
190
}
191
192
case class Prism[S, A](get: S => Option[A], set: S => A => S) {
193
def modifyOption(s: S)(f: A => A): Option[S]
194
}
195
```
196
197
[Optics - Lenses and Prisms](./optics-lenses.md)
198
199
### Polymorphic Functions and Type-Level Programming
200
201
Advanced type-level computations including polymorphic functions that work across different types, natural transformations, type-level arithmetic with natural numbers, and sophisticated type-level logic.
202
203
```scala { .api }
204
trait Poly {
205
def apply[A](a: A)(implicit cse: Case.Aux[this.type, A :: HNil, Out]): Out
206
}
207
208
trait ~>[F[_], G[_]] { // Natural transformation
209
def apply[A](fa: F[A]): G[A]
210
}
211
212
sealed trait Nat { type N <: Nat }
213
trait Succ[P <: Nat] extends Nat
214
```
215
216
[Polymorphic Functions and Type-Level Programming](./poly-typelevel.md)
217
218
### Advanced Features and Utilities
219
220
Specialized features including functional cursors (zippers), tuple operations, compile-time testing utilities, annotation processing, runtime type information, and various conversion utilities for integration with Scala's standard library.
221
222
```scala { .api }
223
case class Zipper[C, L <: HList](left: L, focus: C, right: L)
224
225
def typed[T](t: => T): Unit // Assert expression has type T
226
def typeError(t: String): Unit // Assert code fails to type check
227
228
trait Typeable[T] {
229
def cast(any: Any): Option[T]
230
}
231
```
232
233
[Advanced Features and Utilities](./advanced-utilities.md)