@@ -80,21 +80,6 @@ object TypeLevel {
80
80
def elementLabel (n : Int ) = reflected.label(ordinal)(n + 1 )
81
81
}
82
82
83
- /** A class for mapping between an ADT value and
84
- * the case mirror that represents the value.
85
- */
86
- abstract class Reflected [T ] {
87
-
88
- /** The case mirror corresponding to ADT instance `x` */
89
- def reflect (x : T ): Mirror
90
-
91
- /** The ADT instance corresponding to given `mirror` */
92
- def reify (mirror : Mirror ): T
93
-
94
- /** The companion object of the ADT */
95
- def common : ReflectedClass
96
- }
97
-
98
83
/** The shape of an ADT.
99
84
* This is eithe a product (`Case`) or a sum (`Cases`) of products.
100
85
*/
@@ -110,7 +95,20 @@ object TypeLevel {
110
95
/** Every generic derivation starts with a typeclass instance of this type.
111
96
* It informs that type `T` has shape `S` and also implements runtime reflection on `T`.
112
97
*/
113
- abstract class Shaped [T , S <: Shape ] extends Reflected [T ]
98
+ abstract class Generic [T ] {
99
+
100
+ /** The shape of the `T` */
101
+ type Shape <: TypeLevel .Shape
102
+
103
+ /** The case mirror corresponding to ADT instance `x` */
104
+ def reflect (x : T ): Mirror
105
+
106
+ /** The ADT instance corresponding to given `mirror` */
107
+ def reify (mirror : Mirror ): T
108
+
109
+ /** The companion object of the ADT */
110
+ def common : ReflectedClass
111
+ }
114
112
}
115
113
116
114
// An algebraic datatype
@@ -123,17 +121,14 @@ object Lst {
123
121
// common compiler-generated infrastructure
124
122
import TypeLevel ._
125
123
126
- type Shape [T ] = Shape .Cases [(
127
- Shape .Case [Cons [T ], (T , Lst [T ])],
128
- Shape .Case [Nil .type , Unit ]
129
- )]
130
-
131
124
val reflectedClass = new ReflectedClass (" Cons\000 hd\000 tl\001 Nil" )
132
125
import reflectedClass .mirror
133
126
134
- val NilMirror = mirror(1 )
135
-
136
- implicit def derived$Shaped [T ]: Shaped [Lst [T ], Shape [T ]] = new {
127
+ class GenericLst [T ] extends Generic [Lst [T ]] {
128
+ type Shape = Shape .Cases [(
129
+ Shape .Case [Cons [T ], (T , Lst [T ])],
130
+ Shape .Case [Nil .type , Unit ]
131
+ )]
137
132
def reflect (xs : Lst [T ]): Mirror = xs match {
138
133
case xs : Cons [T ] => mirror(0 , xs)
139
134
case Nil => mirror(1 )
@@ -144,6 +139,7 @@ object Lst {
144
139
}
145
140
def common = reflectedClass
146
141
}
142
+ implicit def GenericLst [T ]: GenericLst [T ] = new GenericLst [T ]
147
143
148
144
// three clauses that could be generated from a `derives` clause
149
145
implicit def derived$Eq [T : Eq ]: Eq [Lst [T ]] = Eq .derived
@@ -158,18 +154,19 @@ object Pair {
158
154
// common compiler-generated infrastructure
159
155
import TypeLevel ._
160
156
161
- type Shape [T ] = Shape .Case [Pair [T ], (T , T )]
162
-
163
157
val reflectedClass = new ReflectedClass (" Pair\000 x\000 y" )
164
158
import reflectedClass .mirror
165
159
166
- implicit def derived$Shape [T ]: Shaped [Pair [T ], Shape [T ]] = new {
160
+ class GenericPair [T ] extends Generic [Pair [T ]] {
161
+ type Shape = Shape .Case [Pair [T ], (T , T )]
162
+
167
163
def reflect (xy : Pair [T ]) =
168
164
mirror(0 , xy)
169
165
def reify (c : Mirror ): Pair [T ] =
170
166
Pair (c(0 ).asInstanceOf , c(1 ).asInstanceOf )
171
167
def common = reflectedClass
172
168
}
169
+ implicit def GenericPair [T ]: GenericPair [T ] = new GenericPair [T ]
173
170
174
171
// clauses that could be generated from a `derives` clause
175
172
implicit def derived$Eq [T : Eq ]: Eq [Pair [T ]] = Eq .derived
@@ -184,15 +181,14 @@ case class Right[R](x: R) extends Either[Nothing, R]
184
181
object Either {
185
182
import TypeLevel ._
186
183
187
- type Shape [L , R ] = Shape .Cases [(
188
- Shape .Case [Left [L ], L *: Unit ],
189
- Shape .Case [Right [R ], R *: Unit ]
190
- )]
191
-
192
184
val reflectedClass = new ReflectedClass (" Left\000 x\001 Right\000 x" )
193
185
import reflectedClass .mirror
194
186
195
- implicit def derived$Shape [L , R ]: Shaped [Either [L , R ], Shape [L , R ]] = new {
187
+ class GenericEither [L , R ] extends Generic [Either [L , R ]] {
188
+ type Shape = Shape .Cases [(
189
+ Shape .Case [Left [L ], L *: Unit ],
190
+ Shape .Case [Right [R ], R *: Unit ]
191
+ )]
196
192
def reflect (e : Either [L , R ]): Mirror = e match {
197
193
case e : Left [L ] => mirror(0 , e)
198
194
case e : Right [R ] => mirror(1 , e)
@@ -203,6 +199,7 @@ object Either {
203
199
}
204
200
def common = reflectedClass
205
201
}
202
+ implicit def GenericEither [L , R ]: GenericEither [L , R ] = new GenericEither [L , R ]
206
203
207
204
implicit def derived$Eq [L : Eq , R : Eq ]: Eq [Either [L , R ]] = Eq .derived
208
205
implicit def derived$Pickler [L : Pickler , R : Pickler ]: Pickler [Either [L , R ]] = Pickler .derived
@@ -240,11 +237,11 @@ object Eq {
240
237
false
241
238
}
242
239
243
- inline def derived [T , S <: Shape ](implicit ev : Shaped [ T , S ]): Eq [T ] = new {
240
+ inline def derived [T , S <: Shape ](implicit ev : Generic [ T ]): Eq [T ] = new {
244
241
def eql (x : T , y : T ): Boolean = {
245
242
val xm = ev.reflect(x)
246
243
val ym = ev.reflect(y)
247
- inline erasedValue[S ] match {
244
+ inline erasedValue[ev. Shape ] match {
248
245
case _ : Shape .Cases [alts] =>
249
246
xm.ordinal == ym.ordinal &&
250
247
eqlCases[alts](xm, ym, 0 )
@@ -303,18 +300,18 @@ object Pickler {
303
300
case _ : Unit =>
304
301
}
305
302
306
- inline def unpickleCase [T , Elems <: Tuple ](r : Reflected [T ], buf : mutable.ListBuffer [Int ], ordinal : Int ): T = {
303
+ inline def unpickleCase [T , Elems <: Tuple ](gen : Generic [T ], buf : mutable.ListBuffer [Int ], ordinal : Int ): T = {
307
304
inline val size = constValue[Tuple .Size [Elems ]]
308
305
inline if (size == 0 )
309
- r .reify(r.common.mirror(ordinal))
306
+ gen .reify(r.common.mirror(ordinal))
310
307
else {
311
308
val elems = new Array [Object ](size)
312
309
unpickleElems[Elems ](buf, elems, 0 )
313
- r .reify(r.common.mirror(ordinal, elems))
310
+ gen .reify(r.common.mirror(ordinal, elems))
314
311
}
315
312
}
316
313
317
- inline def unpickleCases [T , Alts <: Tuple ](r : Reflected [T ], buf : mutable.ListBuffer [Int ], ordinal : Int , n : Int ): T =
314
+ inline def unpickleCases [T , Alts <: Tuple ](r : Generic [T ], buf : mutable.ListBuffer [Int ], ordinal : Int , n : Int ): T =
318
315
inline erasedValue[Alts ] match {
319
316
case _ : (Shape .Case [_, elems] *: alts1) =>
320
317
if (n == ordinal) unpickleCase[T , elems](r, buf, ordinal)
@@ -323,18 +320,18 @@ object Pickler {
323
320
throw new IndexOutOfBoundsException (s " unexpected ordinal number: $ordinal" )
324
321
}
325
322
326
- inline def derived [T , S <: Shape ](implicit ev : Shaped [ T , S ]): Pickler [T ] = new {
323
+ inline def derived [T , S <: Shape ](implicit ev : Generic [ T ]): Pickler [T ] = new {
327
324
def pickle (buf : mutable.ListBuffer [Int ], x : T ): Unit = {
328
325
val xm = ev.reflect(x)
329
- inline erasedValue[S ] match {
326
+ inline erasedValue[ev. Shape ] match {
330
327
case _ : Shape .Cases [alts] =>
331
328
buf += xm.ordinal
332
329
pickleCases[alts](buf, xm, 0 )
333
330
case _ : Shape .Case [_, elems] =>
334
331
pickleElems[elems](buf, xm, 0 )
335
332
}
336
333
}
337
- def unpickle (buf : mutable.ListBuffer [Int ]): T = inline erasedValue[S ] match {
334
+ def unpickle (buf : mutable.ListBuffer [Int ]): T = inline erasedValue[ev. Shape ] match {
338
335
case _ : Shape .Cases [alts] =>
339
336
unpickleCases[T , alts](ev, buf, nextInt(buf), 0 )
340
337
case _ : Shape .Case [_, elems] =>
@@ -379,10 +376,10 @@ object Show {
379
376
throw new MatchError (xm)
380
377
}
381
378
382
- inline def derived [T , S <: Shape ](implicit ev : Shaped [ T , S ]): Show [T ] = new {
379
+ inline def derived [T , S <: Shape ](implicit ev : Generic [ T ]): Show [T ] = new {
383
380
def show (x : T ): String = {
384
381
val xm = ev.reflect(x)
385
- val args = inline erasedValue[S ] match {
382
+ val args = inline erasedValue[ev. Shape ] match {
386
383
case _ : Shape .Cases [alts] =>
387
384
showCases[alts](xm, 0 )
388
385
case _ : Shape .Case [_, elems] =>
@@ -473,4 +470,4 @@ object Test extends App {
473
470
val zs1 = copy(zs)
474
471
showPrintln(zs1)
475
472
assert(eql(zs, zs1))
476
- }
473
+ }
0 commit comments