11---
22layout : doc-page
3- title : Typeclass Derivation
3+ title : Type Class Derivation
44---
55
66Type class derivation is a way to automatically generate given instances for type classes which satisfy some simple
@@ -28,8 +28,9 @@ We say that `Tree` is the _deriving type_ and that the `Eq`, `Ordering` and `Sho
2828
2929### Types supporting ` derives ` clauses
3030
31- Any data type with an available instance of the ` Mirror ` type class supports ` derives ` clauses. Instances of the
32- ` Mirror ` type class are generated automatically by the compiler for,
31+ All data types can have a ` derives ` clause. This document focuses primarily on data types which also have an instance
32+ of the ` Mirror ` type class available. Instances of the ` Mirror ` type class are generated automatically by the compiler
33+ for,
3334
3435+ enums and enum cases
3536+ case classes and case objects
@@ -103,6 +104,7 @@ Mirror.Product {
103104
104105 def fromProduct (p : Product ): MirroredMonoType =
105106 new Branch (...)
107+ }
106108
107109// Mirror for Leaf
108110Mirror .Product {
@@ -114,6 +116,7 @@ Mirror.Product {
114116
115117 def fromProduct (p : Product ): MirroredMonoType =
116118 new Leaf (...)
119+ }
117120```
118121
119122Note the following properties of ` Mirror ` types,
@@ -131,24 +134,29 @@ Note the following properties of `Mirror` types,
131134
132135### Type classes supporting automatic deriving
133136
134- A trait or class can appear in a `derives` clause if its companion object defines a method named `derived`. The type
135- and implementation of a `derived` method for a type class `TC[_]` are arbitrary but it is typically of the following
136- form,
137+ A trait or class can appear in a ` derives ` clause if its companion object defines a method named ` derived ` . The
138+ signature and implementation of a ` derived ` method for a type class ` TC[_] ` are arbitrary but it is typically of the
139+ following form,
137140
138141``` scala
139142 def derived [T ] given Mirror .Of [T ]: TC [T ] = ...
140143```
141144
142145That is, the ` derived ` method takes a given parameter of (some subtype of) type ` Mirror ` which defines the shape of
143- the deriving type `T` , and computes the typeclass implementation according to that shape. This is all that the
146+ the deriving type ` T ` , and computes the type class implementation according to that shape. This is all that the
144147provider of an ADT with a ` derives ` clause has to know about the derivation of a type class instance.
145148
149+ Note that ` derived ` methods may have given ` Mirror ` arguments indirectly (eg. by having a given argument which in turn
150+ has a given ` Mirror ` , or not at all (eg. they might use some completely different user-provided mechanism, for
151+ instance using Dotty macros or runtime reflection). We expect that (direct or indirect) ` Mirror ` based implementations
152+ will be the most common and that is what this document emphasises.
153+
146154Type class authors will most likely use higher level derivation or generic programming libraries to implement
147- `derived` methods. The rest of this page gives an example of how a `derived` method might be implemented using _only_
148- the low level facilities described above and Dotty ' s general metaprogramming features. It is not anticipated that type
149- class authors would normally implement a `derived` method in this way, however this walkthrough can be taken as a
150- guide for authors of the higher level derivation libraries that we expect typical type class authors will use (for a
151- fully worked out example of such a library, see [shapeless 3 ](https:// github.com/ milessabin/ shapeless/ tree/ shapeless- 3 )).
155+ ` derived ` methods. An example of how a ` derived ` method might be implemented using _ only_ the low level facilities
156+ described above and Dotty's general metaprogramming features is provided below . It is not anticipated that type class
157+ authors would normally implement a ` derived ` method in this way, however this walkthrough can be taken as a guide for
158+ authors of the higher level derivation libraries that we expect typical type class authors will use (for a fully
159+ worked out example of such a library, see [ shapeless 3] ( https://github.com/milessabin/shapeless/tree/shapeless-3 ) ).
152160
153161#### How to write a type class ` derived ` method using low level mechanisms
154162
@@ -341,8 +349,8 @@ The framework described here enables all three of these approaches without manda
341349
342350### Deriving instances elsewhere
343351
344- Sometimes one would like to derive a typeclass instance for an ADT after the ADT is defined, without being able to
345- change the code of the ADT itself. To do this , simply define an instance using the `derived` method of the typeclass
352+ Sometimes one would like to derive a type class instance for an ADT after the ADT is defined, without being able to
353+ change the code of the ADT itself. To do this, simply define an instance using the ` derived ` method of the type class
346354as right-hand side. E.g, to implement ` Ordering ` for ` Option ` define,
347355
348356``` scala
@@ -365,7 +373,7 @@ ConstrApps ::= ConstrApp {‘with’ ConstrApp}
365373
366374### Discussion
367375
368- This typeclass derivation framework is intentionally very small and low- level. There are essentially two pieces of
376+ This type class derivation framework is intentionally very small and low-level. There are essentially two pieces of
369377infrastructure in compiler-generated ` Mirror ` instances,
370378
371379+ type members encoding properties of the mirrored types.
@@ -380,7 +388,7 @@ feature small enough to make it possible to provide `Mirror` instances _uncondit
380388Whilst ` Mirrors ` encode properties precisely via type members, the value level ` ordinal ` and ` fromProduct ` are
381389somewhat weakly typed (because they are defined in terms of ` MirroredMonoType ` ) just like the members of ` Product ` .
382390This means that code for generic type classes has to ensure that type exploration and value selection proceed in
383- lockstep and it has to assert this conformance in some places using casts. If generic typeclasses are correctly
391+ lockstep and it has to assert this conformance in some places using casts. If generic type classes are correctly
384392written these casts will never fail.
385393
386394As mentioned, however, the compiler-provided mechansim is intentionally very low level and it is anticipated that
0 commit comments