Skip to content

Commit 1929522

Browse files
committed
Flesh out docs
1 parent 219318e commit 1929522

File tree

1 file changed

+43
-27
lines changed

1 file changed

+43
-27
lines changed

tests/run/typeclass-derivation2c.scala

+43-27
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,9 @@ import scala.annotation.tailrec
55

66
// -- Classes and Objects of the Derivation Framework ----------------------------------
77

8-
/** Simulates the scala.reflect package */
8+
/** Core classes. In the current implementation these are in the scala.reflect package */
99
object Deriving {
1010

11-
object EmptyProduct extends Product {
12-
def canEqual(that: Any): Boolean = true
13-
def productElement(n: Int) = throw new IndexOutOfBoundsException
14-
def productArity = 0
15-
}
16-
17-
/** Helper class to turn arrays into products */
18-
class ArrayProduct(val elems: Array[AnyRef]) extends Product {
19-
def canEqual(that: Any): Boolean = true
20-
def productElement(n: Int) = elems(n)
21-
def productArity = elems.length
22-
override def productIterator: Iterator[Any] = elems.iterator
23-
def update(n: Int, x: Any) = elems(n) = x.asInstanceOf[AnyRef]
24-
}
25-
26-
def productElement[T](x: Any, idx: Int) = x.asInstanceOf[Product].productElement(idx).asInstanceOf[T]
27-
2811
/** The Generic class hierarchy allows typelevel access to
2912
* enums, case classes and objects, and their sealed parents.
3013
*/
@@ -48,22 +31,47 @@ object Deriving {
4831
erased def alternative(n: Int): Generic[_ <: T] = ???
4932
}
5033

51-
/** A Generic for a product type */
34+
/** The Generic for a product type */
5235
abstract class Product[T] extends Generic[T] {
36+
37+
/** The types of the elements */
5338
type ElemTypes <: Tuple
39+
40+
/** The name of the whole product type */
5441
type CaseLabel <: String
42+
43+
/** The names of the product elements */
5544
type ElemLabels <: Tuple
5645

46+
/** Create a new instance of type `T` with elements taken from product `p`. */
5747
def fromProduct(p: scala.Product): T
5848
}
5949

50+
/** The Generic for a singleton */
6051
trait Singleton[T] extends Generic[T] {
52+
53+
/** The name of the singleton */
54+
type CaseLabel <: String
55+
56+
/** The represented value */
6157
inline def singletonValue = implicit match {
6258
case ev: ValueOf[T] => ev.value
6359
}
64-
type CaseLabel <: String
6560
}
6661
}
62+
63+
/** Helper class to turn arrays into products */
64+
class ArrayProduct(val elems: Array[AnyRef]) extends Product {
65+
def canEqual(that: Any): Boolean = true
66+
def productElement(n: Int) = elems(n)
67+
def productArity = elems.length
68+
override def productIterator: Iterator[Any] = elems.iterator
69+
def update(n: Int, x: Any) = elems(n) = x.asInstanceOf[AnyRef]
70+
}
71+
72+
/** Helper method to select a product element */
73+
def productElement[T](x: Any, idx: Int) =
74+
x.asInstanceOf[Product].productElement(idx).asInstanceOf[T]
6775
}
6876
import Deriving._
6977

@@ -183,6 +191,18 @@ object Right extends Generic.Product[Right[_]] {
183191
// -- Type classes ------------------------------------------------------------
184192

185193
// Everything here is hand-written by the authors of the derivable typeclasses
194+
// The same schema is used throughout.
195+
//
196+
// - A typeclass implements an inline `derived` method, given a `Generic` instance.
197+
// - Each implemented typeclass operation `xyz` calls 4 inline helper methods:
198+
// 1. `xyzCases` for sums,
199+
// 2. `xyzProduct` for products,
200+
// 3. `xyzElems` stepping through the elements of a product,
201+
// 4. `tryXyz` for searching the implicit to handles a single element.
202+
// - The first three methods have two parameter lists. The first parameter
203+
// list contains inline parameters that guide the code generation, whereas
204+
// the second parameter list contains parameters that show up in the
205+
// generated code. (This is done just to make things clearer).
186206

187207
// Equality typeclass
188208
trait Eq[T] {
@@ -286,13 +306,9 @@ object Pickler {
286306

287307
inline def unpickleProduct[T](g: Generic.Product[T])(buf: mutable.ListBuffer[Int]): T = {
288308
inline val size = constValue[Tuple.Size[g.ElemTypes]]
289-
inline if (size == 0)
290-
g.fromProduct(EmptyProduct)
291-
else {
292-
val elems = new Array[Object](size)
293-
unpickleElems[g.ElemTypes](0)(buf, elems)
294-
g.fromProduct(ArrayProduct(elems))
295-
}
309+
val elems = new Array[Object](size)
310+
unpickleElems[g.ElemTypes](0)(buf, elems)
311+
g.fromProduct(ArrayProduct(elems))
296312
}
297313

298314
inline def unpickleCases[T](g: Generic.Sum[T], n: Int)(buf: mutable.ListBuffer[Int], ord: Int): T =

0 commit comments

Comments
 (0)