### Derive Monoid Type Class for Scala ADT Source: https://github.com/typelevel/shapeless-3/blob/main/README.md Example of deriving a Monoid type class for a Scala ADT using shapeless 3. Requires the Monoid type class definition and the ADT definition. The `derived` method simplifies the process. ```scala import shapeless3.deriving.* // Type class definition, eg. from Cats trait Monoid[A]: def empty: A def combine(x: A, y: A): A extension (x: A) def |+| (y: A): A = combine(x, y) object Monoid: given Monoid[Unit] with def empty: Unit = () def combine(x: Unit, y: Unit): Unit = () given Monoid[Boolean] with def empty: Boolean = false def combine(x: Boolean, y: Boolean): Boolean = x || y given Monoid[Int] with def empty: Int = 0 def combine(x: Int, y: Int): Int = x+y given Monoid[String] with def empty: String = "" def combine(x: String, y: String): String = x+y given monoidGen[A](using inst: K0.ProductInstances[Monoid, A]): Monoid[A] with def empty: A = inst.construct([t] => (ma: Monoid[t]) => ma.empty) def combine(x: A, y: A): A = inst.map2(x, y)([t] => (mt: Monoid[t], t0: t, t1: t) => mt.combine(t0, t1)) inline def derived[A](using gen: K0.ProductGeneric[A]): Monoid[A] = monoidGen // ADT definition case class ISB(i: Int, s: String, b: Boolean) derives Monoid val a = ISB(23, "foo", true) val b = ISB(13, "bar", false) val c = a |+| b // == ISB(36, "foobar", true) ``` -------------------------------- ### Derive Functor Type Class for Scala Enum Source: https://github.com/typelevel/shapeless-3/blob/main/README.md Example of deriving a Functor type class for a Scala enum using shapeless 3. The `derives Functor` annotation automatically generates the Functor instance. ```scala enum Opt[+A] derives Functor: case Sm[+A](value: A) case Nn Sm("foo").map(_.length) // == Sm(3) ``` -------------------------------- ### Derive Type Classes for Sum and Product Types with K0 Source: https://context7.com/typelevel/shapeless-3/llms.txt Uses K0.CoproductInstances and K0.ProductInstances to derive type classes for sealed traits and case classes. ```scala import shapeless3.deriving.* trait Show[T]: def show(t: T): String object Show: given Show[Int] = (i: Int) => i.toString given Show[String] = (s: String) => s"\"$s\"" // Product derivation with labelling given showGen[T](using inst: K0.ProductInstances[Show, T], labelling: Labelling[T]): Show[T] with def show(t: T): String = if labelling.elemLabels.isEmpty then labelling.label else labelling.elemLabels.zipWithIndex .map((label, i) => s"$label: ${inst.project(t)(i)([t] => (st: Show[t], pt: t) => st.show(pt))}") .mkString(s"${labelling.label}(", ", ", ")") // Coproduct derivation - fold over the actual variant given showGenC[T](using inst: K0.CoproductInstances[Show, T]): Show[T] with def show(t: T): String = inst.fold(t)([t] => (st: Show[t], t: t) => st.show(t)) inline def derived[A](using gen: K0.Generic[A]): Show[A] = gen.derive(showGen, showGenC) // Works for both products and sums case class Person(name: String, age: Int) derives Show sealed trait Option[+A] derives Show case class Some[A](value: A) extends Option[A] case object None extends Option[Nothing] summon[Show[Person]].show(Person("Alice", 30)) // Person(name: "Alice", 30) summon[Show[Option[Int]]].show(Some(42)) // Some(value: 42) ``` -------------------------------- ### Add shapeless3-deriving to project build Source: https://github.com/typelevel/shapeless-3/blob/main/README.md Instructions for adding the shapeless3-deriving module to a Scala project's build configuration. This is typically done in the `build.sbt` file. ```scala libraryDependencies ++= Seq("org.typelevel" %% "shapeless3-deriving" % "3.4.0") ``` -------------------------------- ### Import Shapeless 3 Deriving Module Source: https://context7.com/typelevel/shapeless-3/llms.txt Import the deriving module from shapeless3 to access its generic programming features. ```scala import shapeless3.deriving.* ``` -------------------------------- ### Derive Foldable for Containers with K1 Source: https://context7.com/typelevel/shapeless-3/llms.txt Implements Foldable for recursive data structures using K1.ProductInstances. ```scala import shapeless3.deriving.* import cats.Eval trait Foldable[F[_]]: def foldLeft[A, B](fa: F[A])(b: B)(f: (B, A) => B): B def foldRight[A, B](fa: F[A])(lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] object Foldable: given Foldable[Id] with def foldLeft[A, B](fa: A)(b: B)(f: (B, A) => B): B = f(b, fa) def foldRight[A, B](fa: A)(lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = f(fa, lb) given [X]: Foldable[Const[X]] with def foldLeft[A, B](fa: X)(b: B)(f: (B, A) => B): B = b def foldRight[A, B](fa: X)(lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = lb given foldableProduct[F[_]](using inst: K1.ProductInstances[Foldable, F]): Foldable[F] with def foldLeft[A, B](fa: F[A])(b: B)(f: (B, A) => B): B = inst.foldLeft[A, B](fa)(b)( [t[_]] => (acc: B, fd: Foldable[t], t0: t[A]) => Continue(fd.foldLeft(t0)(acc)(f)) ) def foldRight[A, B](fa: F[A])(lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = inst.foldRight[A, Eval[B]](fa)(lb)( [t[_]] => (fd: Foldable[t], t0: t[A], acc: Eval[B]) => Continue(Eval.defer(fd.foldRight(t0)(acc)(f))) ) inline def derived[F[_]](using gen: K1.Generic[F]): Foldable[F] = gen.derive(foldableProduct, foldableCoproduct) sealed trait Tree[+A] derives Foldable case class Leaf[A](value: A) extends Tree[A] case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A] val tree: Tree[Int] = Branch(Leaf(1), Branch(Leaf(2), Leaf(3))) Foldable[Tree].foldLeft(tree)(0)(_ + _) // 6 ``` -------------------------------- ### Add Shapeless 3 Dependency Source: https://context7.com/typelevel/shapeless-3/llms.txt Add the shapeless3-deriving library to your build.sbt file to use Shapeless 3. ```scala libraryDependencies += "org.typelevel" %% "shapeless3-deriving" % "3.4.0" ``` -------------------------------- ### Deriving Bifunctor for Binary Type Constructors Source: https://context7.com/typelevel/shapeless-3/llms.txt Enables derivation of type classes for types with two type parameters, such as Bifunctor for Either and Tuple2. Requires importing shapeless3.deriving. ```scala import shapeless3.deriving.* trait Bifunctor[F[_, _]]: def bimap[A, B, C, D](fab: F[A, B])(f: A => C, g: B => D): F[C, D] object Bifunctor: given Bifunctor[Tuple2] with def bimap[A, B, C, D](fab: (A, B))(f: A => C, g: B => D): (C, D) = (f(fab._1), g(fab._2)) given Bifunctor[Either] with def bimap[A, B, C, D](fab: Either[A, B])(f: A => C, g: B => D): Either[C, D] = fab match case Left(a) => Left(f(a)) case Right(b) => Right(g(b)) given bifunctorGen[F[_, _]](using inst: K2.Instances[Bifunctor, F]): Bifunctor[F] with def bimap[A, B, C, D](fab: F[A, B])(f: A => C, g: B => D): inst.map(fab)([t[_, _]] => (bft: Bifunctor[t], tab: t[A, B]) => bft.bimap(tab)(f, g)) given Bifunctor[K2.Id1] with def bimap[A, B, C, D](a: A)(f: A => C, g: B => D): C = f(a) given Bifunctor[K2.Id2] with def bimap[A, B, C, D](b: B)(f: A => C, g: B => D): D = g(b) inline def derived[F[_, _]](using gen: K2.Generic[F]): Bifunctor[F] = bifunctorGen // Custom bifunctor sum type sealed trait ListF[+A, +R] derives Bifunctor case class ConsF[+A, +R](hd: A, tl: R) extends ListF[A, R] case object NilF extends ListF[Nothing, Nothing] val cons: ListF[String, Int] = ConsF("hello", 42) Bifunctor[ListF].bimap(cons)(_.length, _ * 2) // ConsF(5, 84) ``` -------------------------------- ### Accessing Field and Type Names with Labelling Source: https://context7.com/typelevel/shapeless-3/llms.txt Provides runtime access to type and field names, essential for implementing Show, JSON serialization, and similar type classes. Requires importing shapeless3.deriving. ```scala import shapeless3.deriving.* case class Person(name: String, age: Int) val labelling = summon[Labelling[Person]] labelling.label // "Person" labelling.elemLabels // IndexedSeq("name", "age") // Use in type class derivation trait JsonEncoder[T]: def encode(t: T): String object JsonEncoder: given JsonEncoder[String] = s => s"\"$s\"" given JsonEncoder[Int] = _.toString given encGen[T](using inst: K0.ProductInstances[JsonEncoder, T], labelling: Labelling[T]): JsonEncoder[T] with def encode(t: T): val fields = labelling.elemLabels.zipWithIndex.map { (name, i) => val value = inst.project(t)(i)([t] => (enc: JsonEncoder[t], v: t) => enc.encode(v)) s"\"$name\": $value" } s"{ ${fields.mkString(", ")} }" inline def derived[A](using gen: K0.ProductGeneric[A]): JsonEncoder[A] = encGen case class User(id: Int, email: String) derives JsonEncoder summon[JsonEncoder[User]].encode(User(1, "alice@example.com")) // { "id": 1, "email": "alice@example.com" } ``` -------------------------------- ### Add Shapeless 3 Deriving Dependency Source: https://github.com/typelevel/shapeless-3/blob/main/docs/index.md Include the shapeless3-deriving library in your project's build.sbt file. Replace '@VERSION@' with the desired version. ```scala libraryDependencies += "org.typelevel" %% "shapeless3-deriving" % "@VERSION@" ``` -------------------------------- ### Derive Eq Type Class for Product Types Source: https://context7.com/typelevel/shapeless-3/llms.txt Defines and derives the Eq type class for product types (case classes) using Shapeless 3's generic derivation. It utilizes foldLeft2 for short-circuiting equality comparisons. ```scala import shapeless3.deriving.* trait Eq[A]: def eqv(x: A, y: A): Boolean object Eq: given Eq[Int] with def eqv(x: Int, y: Int): Boolean = x == y given Eq[String] with def eqv(x: String, y: String): Boolean = x == y given Eq[Boolean] with def eqv(x: Boolean, y: Boolean): Boolean = x == y // Use foldLeft2 for short-circuit equality comparison given eqGen[A](using inst: K0.ProductInstances[Eq, A]): Eq[A] with def eqv(x: A, y: A): Boolean = inst.foldLeft2(x, y)(true: Boolean)( [t] => (acc: Boolean, eqt: Eq[t], t0: t, t1: t) => Complete(!eqt.eqv(t0, t1))(false)(true) // Short-circuit on first mismatch ) inline def derived[A](using gen: K0.ProductGeneric[A]): Eq[A] = eqGen case class Point(x: Int, y: Int) derives Eq val eq = summon[Eq[Point]] eq.eqv(Point(1, 2), Point(1, 2)) // true eq.eqv(Point(1, 2), Point(1, 3)) // false ``` -------------------------------- ### Retrieve Annotations with Annotation and Annotations Source: https://context7.com/typelevel/shapeless-3/llms.txt Use Annotation to retrieve type-level annotations and Annotations for field-level annotations at compile time. ```scala import shapeless3.deriving.* // Define annotation types case class MaxLength(value: Int) extends scala.annotation.StaticAnnotation case class Required() extends scala.annotation.StaticAnnotation @Required() case class Config( @MaxLength(100) name: String, port: Int ) // Get type-level annotation val typeAnnotation = Annotation[Required, Config] typeAnnotation() // Required() // Get field annotations val fieldAnnotations = Annotations[MaxLength, Config] // Type: (Some[MaxLength], None.type) fieldAnnotations() // (Some(MaxLength(100)), None) // Get all annotations for all fields val allAnnotations = AllAnnotations[Config] allAnnotations() // ((MaxLength(100)), ()) ``` -------------------------------- ### Derive Functors for Higher-Kinded Types with K1 Source: https://context7.com/typelevel/shapeless-3/llms.txt Enables automatic derivation of Functor instances for parameterized types using K1.Instances. ```scala import shapeless3.deriving.* trait Functor[F[_]]: def map[A, B](fa: F[A])(f: A => B): F[B] object Functor: given Functor[Id] with def map[A, B](a: A)(f: A => B): B = f(a) // Generic derivation for F[_] types given functorGen[F[_]](using inst: K1.Instances[Functor, F]): Functor[F] with def map[A, B](fa: F[A])(f: A => B): F[B] = inst.map(fa)([t[_]] => (ft: Functor[t], ta: t[A]) => ft.map(ta)(f)) given [T]: Functor[Const[T]] with def map[A, B](t: T)(f: A => B): T = t inline def derived[F[_]](using gen: K1.Generic[F]): Functor[F] = functorGen // Custom option type with automatic Functor derivation enum Opt[+A] derives Functor: case Sm(value: A) case Nn // Recursive list type sealed trait CList[+A] derives Functor case class CCons[+A](hd: A, tl: CList[A]) extends CList[A] case object CNil extends CList[Nothing] val opt = Opt.Sm("hello") Functor[Opt].map(opt)(_.length) // Sm(5) val list: CList[String] = CCons("foo", CCons("bar", CNil)) Functor[CList].map(list)(_.toUpperCase) // CCons("FOO", CCons("BAR", CNil)) ``` -------------------------------- ### Implement Short-Circuit Folding with CompleteOr Source: https://context7.com/typelevel/shapeless-3/llms.txt CompleteOr allows early termination in fold operations, useful for efficient comparison logic. ```scala import shapeless3.deriving.* trait Ord[A]: def compare(x: A, y: A): Int object Ord: given Ord[Int] with def compare(x: Int, y: Int): Int = x - y given Ord[String] with def compare(x: String, y: String): Int = x.compare(y) given ordGen[A](using inst: K0.ProductInstances[Ord, A]): Ord[A] with def compare(x: A, y: A): Int = inst.foldLeft2(x, y)(0: Int)( [t] => (acc: Int, ord: Ord[t], t0: t, t1: t) => val cmp = ord.compare(t0, t1) // Short-circuit: if comparison is non-zero, return immediately Complete(cmp != 0)(cmp)(acc) ) inline def derived[A](using gen: K0.ProductGeneric[A]): Ord[A] = ordGen case class Point(x: Int, y: Int) derives Ord val ord = summon[Ord[Point]] ord.compare(Point(1, 2), Point(1, 2)) // 0 ord.compare(Point(1, 2), Point(2, 1)) // -1 (short-circuits after x comparison) ord.compare(Point(1, 2), Point(1, 3)) // -1 (compares y after x matches) ``` -------------------------------- ### Derive Higher-Order Functor (FunctorK) Source: https://github.com/typelevel/shapeless-3/blob/main/README.md Demonstrates deriving a higher-order functor (FunctorK) for a data type parameterized with an effect. This allows mapping over the effectful type using `mapK`. ```scala // An Option like type, with a default enum OptionD[T]: case Given(value: T) case Default(value: T) def fold: T = this match { case Given(t) => t case Default(t) => t } object OptionD: val fold: OptionD ~> Id = [t] => (ot: OptionD[t]) => ot.fold // A data type parameterized with an effect case class OrderF[F[_]]( item: F[String], quantity: F[Int] ) derives FunctorK val incompleteOrder = OrderF(Given("Epoisse"), Default(1)) val completeOrder = FunctorK[OrderF].mapK(incompleteOrder)(OptionD.fold) // == OrderF[Id]("Epoisse", 1) ``` -------------------------------- ### Derive Monoid Type Class for Regular Types Source: https://context7.com/typelevel/shapeless-3/llms.txt Defines and derives the Monoid type class for regular types (kind *) using Shapeless 3's generic derivation. Requires explicit instances for base types and generic derivation for product types. ```scala import shapeless3.deriving.* // Define a type class trait Monoid[A]: def empty: A def combine(x: A, y: A): A object Monoid: given Monoid[Int] with def empty: Int = 0 def combine(x: Int, y: Int): Int = x + y given Monoid[String] with def empty: String = "" def combine(x: String, y: String): String = x + y given Monoid[Boolean] with def empty: Boolean = false def combine(x: Boolean, y: Boolean): Boolean = x || y // Generic derivation for product types given monoidGen[A](using inst: K0.ProductInstances[Monoid, A]): Monoid[A] with def empty: A = inst.construct([t] => (ma: Monoid[t]) => ma.empty) def combine(x: A, y: A): A = inst.map2(x, y)( [t] => (mt: Monoid[t], t0: t, t1: t) => mt.combine(t0, t1) ) inline def derived[A](using gen: K0.ProductGeneric[A]): Monoid[A] = monoidGen // Usage - automatic derivation case class ISB(i: Int, s: String, b: Boolean) derives Monoid val a = ISB(23, "foo", true) val b = ISB(13, "bar", false) val monoid = summon[Monoid[ISB]] monoid.empty // ISB(0, "", false) monoid.combine(a, b) // ISB(36, "foobar", true) ``` -------------------------------- ### Deriving FunctorK for Higher-Order Functors Source: https://context7.com/typelevel/shapeless-3/llms.txt Enables derivation of type classes for types parameterized by type constructors, useful for effect-polymorphic data types. Requires importing shapeless3.deriving. ```scala import shapeless3.deriving.* // Natural transformation between type constructors type ~>[A[_], B[_]] = [t] => A[t] => B[t] trait FunctorK[H[_[_]]]: def mapK[A[_], B[_]](af: H[A])(f: A ~> B): H[B] object FunctorK: inline def apply[H[_[_]]](using fh: FunctorK[H]): FunctorK[H] = fh given [T]: FunctorK[K11.Id[T]] with def mapK[A[_], B[_]](at: A[T])(f: A ~> B): B[T] = f(at) given functorKGen[H[_[_]]](using inst: => K11.Instances[FunctorK, H]): FunctorK[H] with def mapK[A[_], B[_]](ha: H[A])(f: A ~> B): inst.map(ha)([t[_[_]]] => (ft: FunctorK[t], ta: t[A]) => ft.mapK(ta)(f)) given [T]: FunctorK[K11.Const[T]] with def mapK[A[_], B[_]](t: T)(f: A ~> B): T = t inline def derived[F[_[_]]](using gen: K11.Generic[F]): FunctorK[F] = functorKGen // Effect-polymorphic data type case class Order[F[_]](item: F[String], quantity: F[Int]) derives FunctorK // Option-like type with default values sealed trait OptionD[T]: def fold: T object OptionD: val fold: OptionD ~> Id = [t] => (od: OptionD[t]) => od.fold case class Given[T](value: T) extends OptionD[T]: def fold: T = value case class Default[T](value: T) extends OptionD[T]: def fold: T = value // Transform from OptionD to Id by applying fold val incompleteOrder = Order[OptionD](Given("Epoisse"), Default(1)) val completeOrder = FunctorK[Order].mapK(incompleteOrder)(OptionD.fold) // Order[Id]("Epoisse", 1) ``` -------------------------------- ### Compose Typeclass Instances with Derived and OrElse Source: https://context7.com/typelevel/shapeless-3/llms.txt Derived and OrElse facilitate the composition of typeclass instances, allowing for fallback mechanisms. ```scala import shapeless3.deriving.* trait Show[T]: def show(t: T): String object Show: // ... base instances ... // Use OrElse to prefer explicit instances over derived ones given showOrDerived[A](using inst: K0.ProductInstances[Show |: Derived, A], labelling: Labelling[A] ): Show[A] = ??? inline def derived[A](using gen: K0.Generic[A]): Show[A] = ??? // Derived wrapper for third-party type class derivation given Derived[Show[Long]] = Derived(_.toString) // OrElse selects between primary and fallback instances given Int = 42 given String = "Shapeless" val result = summon[OrElse[Int, String]].unify // 42 (prefers Int) // When Int is not available val fallback = summon[OrElse[Double, String]].unify // "Shapeless" ``` -------------------------------- ### Perform Type-Safe Casting with Typeable Source: https://context7.com/typelevel/shapeless-3/llms.txt Typeable provides runtime casting that respects generic type parameters and supports pattern matching via TypeCase. ```scala import shapeless3.typeable.* import shapeless3.typeable.syntax.typeable.* // Basic type-safe casting val x: Any = List(1, 2, 3) x.cast[List[Int]] // Some(List(1, 2, 3)) x.cast[List[String]] // None - element types checked! val y: Any = Map("a" -> 1, "b" -> 2) y.cast[Map[String, Int]] // Some(Map(a -> 1, b -> 2)) y.cast[Map[String, String]] // None // Works with case classes case class Box[A](value: A) val box: Any = Box(42) box.cast[Box[Int]] // Some(Box(42)) box.cast[Box[String]] // None // TypeCase for pattern matching val IntList = TypeCase[List[Int]] val StringList = TypeCase[List[String]] def process(x: Any): String = x match case IntList(ints) => s"Ints: ${ints.sum}" case StringList(strs) => s"Strings: ${strs.mkString(", ")}" case _ => "Unknown" process(List(1, 2, 3)) // "Ints: 6" process(List("a", "b")) // "Strings: a, b" // Get type description Typeable[List[Int]].describe // "List[Int]" Typeable[Either[String, Int]].describe // "Either[String, Int]" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.