or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

advanced-utilities.mdcoproduct-unions.mdgeneric-derivation.mdhlist-collections.mdindex.mdoptics-lenses.mdpoly-typelevel.mdrecords-fields.md
tile.json

tessl/maven-com-chuusai--shapeless_2-12

A type class and dependent type based generic programming library for Scala

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/com.chuusai/shapeless_2.12@2.3.x

To install, run

npx @tessl/cli install tessl/maven-com-chuusai--shapeless_2-12@2.3.0

index.mddocs/

Shapeless

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.

Package Information

  • Package Name: com.chuusai:shapeless_2.12
  • Package Type: Maven (SBT)
  • Language: Scala
  • Installation: libraryDependencies += "com.chuusai" %% "shapeless" % "2.3.13"

Core Imports

import shapeless._

For specific functionality:

import shapeless.{HList, ::, HNil, Generic, Coproduct, :+:, CNil}
import shapeless.ops.hlist._
import shapeless.ops.coproduct._
import shapeless.syntax.hlist._
import shapeless.syntax.coproduct._
import shapeless.labelled.FieldType
import shapeless.tag.@@

Common syntax extensions:

import shapeless.syntax.singleton._  // Narrow type literals
import shapeless.syntax.std.tuple._  // Tuple conversions
import shapeless.syntax.std.function._  // Function conversions

Basic Usage

import shapeless._

// Define a case class
case class Person(name: String, age: Int, active: Boolean)

// Get generic representation
val gen = Generic[Person]
val person = Person("Alice", 30, true)

// Convert to HList
val hlist = gen.to(person)  // String :: Int :: Boolean :: HNil

// Access elements by type
val name: String = hlist.select[String]
val age: Int = hlist.select[Int]

// Convert back to case class
val reconstructed = gen.from(hlist)

// Work with heterogeneous lists directly
val mixed: String :: Int :: Boolean :: HNil = "test" :: 42 :: true :: HNil
val length = mixed.length  // Nat._3 (compile-time known)
val head = mixed.head      // "test"
val tail = mixed.tail      // Int :: Boolean :: HNil

Architecture

Shapeless is built around several key architectural concepts:

  • Type-Level Programming: Computations performed at compile-time using Scala's type system
  • Heterogeneous Data Structures: Collections that can contain different types while preserving type information
  • Generic Representations: Automatic conversion between user-defined types and generic forms
  • Dependent Types: Types that depend on values, enabling precise type-level constraints
  • Automatic Derivation: Compile-time generation of type class instances using macros

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.

Capabilities

Core Type System and Infrastructure

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.

type Id[+T] = T
type Const[C] = { type λ[T] = C }

// Type inequalities
trait =:!=[A, B] extends Serializable
trait <:!<[A, B] extends Serializable

// Logical type operators
type ¬[T] = T => Nothing
type ¬¬[T] = ¬[¬[T]]
type ∧[T, U] = T with U
type ∨[T, U] = ¬[¬[T] ∧ ¬[U]]

// Type-lambda helpers for context bounds
type |∨|[T, U] = { type λ[X] = ¬¬[X] <:< (T ∨ U) }
type |¬|[T] = { type λ[U] = U <:!< T }

// Quantifiers
type ∃[P[_]] = P[T] forSome { type T }
type ∀[P[_]] = ¬[∃[({ type λ[X] = ¬[P[X]]})#λ]]

// Dependent function types
trait DepFn0 { type Out; def apply(): Out }
trait DepFn1[T] { type Out; def apply(t: T): Out }
trait DepFn2[T, U] { type Out; def apply(t: T, u: U): Out }

// Macro-based cached implicit resolution
def cachedImplicit[T]: T = macro CachedImplicitMacros.cachedImplicitImpl[T]

HLists and Heterogeneous Collections

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.

sealed trait HList
final case class ::[+H, +T <: HList](head: H, tail: T) extends HList
sealed trait HNil extends HList

// Construction and access
def apply[T](t: T): T :: HNil
def select[U]: U  // Select element by type
def at[N <: Nat]: Out  // Access by position

HLists and Heterogeneous Collections

Coproducts and Union Types

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.

sealed trait Coproduct
sealed trait :+:[+H, +T <: Coproduct] extends Coproduct
final case class Inl[+H, +T <: Coproduct](head: H) extends (H :+: T)
final case class Inr[+H, +T <: Coproduct](tail: T) extends (H :+: T)

// Injection and selection  
def inject[I]: I => Coproduct
def select[T]: Option[T]

Coproducts and Union Types

Generic Programming and Automatic Derivation

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.

trait Generic[A] {
  type Repr
  def to(a: A): Repr
  def from(repr: Repr): A
}

trait LabelledGeneric[A] {
  type Repr
  def to(a: A): Repr  // Preserves field names as types
  def from(repr: Repr): A
}

Generic Programming and Automatic Derivation

Records and Named Field Access

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.

type FieldType[K, +V] = V @@ KeyTag[K, V]

object field[K] extends FieldOf[K]
def selectDynamic(field: String): FieldType[K, V]
def updatedDynamic[V](field: String, value: V): Record

Records and Named Field Access

Optics - Lenses and Prisms

Functional programming patterns for composable data access and transformation. Provides type-safe navigation and modification of nested data structures with automatic derivation.

case class Lens[S, A](get: S => A, set: S => A => S) {
  def modify(s: S)(f: A => A): S
}

case class Prism[S, A](get: S => Option[A], set: S => A => S) {
  def modifyOption(s: S)(f: A => A): Option[S]
}

Optics - Lenses and Prisms

Polymorphic Functions and Type-Level Programming

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.

trait Poly {
  def apply[A](a: A)(implicit cse: Case.Aux[this.type, A :: HNil, Out]): Out
}

trait ~>[F[_], G[_]] {  // Natural transformation
  def apply[A](fa: F[A]): G[A]
}

sealed trait Nat { type N <: Nat }
trait Succ[P <: Nat] extends Nat

Polymorphic Functions and Type-Level Programming

Advanced Features and Utilities

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.

case class Zipper[C, L <: HList](left: L, focus: C, right: L)

def typed[T](t: => T): Unit  // Assert expression has type T
def typeError(t: String): Unit  // Assert code fails to type check

trait Typeable[T] {
  def cast(any: Any): Option[T]
}

Advanced Features and Utilities