@@ -11,21 +11,23 @@ object Deriving {
1111 /** The Generic class hierarchy allows typelevel access to
1212 * enums, case classes and objects, and their sealed parents.
1313 */
14- sealed abstract class Mirror [T ]
14+ sealed abstract class Mirror { type MirroredType }
15+
16+ type MirrorOf [T ] = Mirror { type MirroredType = T }
1517
1618 object Mirror {
1719
1820 /** The Mirror for a sum type */
19- trait Sum [ T ] extends Mirror [ T ] { self =>
21+ trait Sum extends Mirror { self =>
2022
2123 type ElemTypes <: Tuple
2224
2325 /** The ordinal number of the case class of `x`. For enums, `ordinal(x) == x.ordinal` */
24- def ordinal (x : T ): Int
26+ def ordinal (x : MirroredType ): Int
2527 }
2628
2729 /** The Mirror for a product type */
28- trait Product [ T ] extends Mirror [ T ] {
30+ trait Product extends Mirror {
2931
3032 /** The types of the elements */
3133 type ElemTypes <: Tuple
@@ -37,8 +39,11 @@ object Deriving {
3739 type ElemLabels <: Tuple
3840
3941 /** Create a new instance of type `T` with elements taken from product `p`. */
40- def fromProduct (p : scala.Product ): T
42+ def fromProduct (p : scala.Product ): MirroredType
4143 }
44+
45+ type SumOf [T ] = Sum { type MirroredType = T }
46+ type ProductOf [T ] = Product { type MirroredType = T }
4247 }
4348
4449 /** Helper class to turn arrays into products */
@@ -61,37 +66,43 @@ import Deriving._
6166
6267sealed trait Lst [+ T ] // derives Eq, Pickler, Show
6368
64- object Lst extends Mirror .Sum [Lst [_]] {
69+ object Lst extends Mirror .Sum {
70+ type MirroredType = Lst [_]
6571
6672 def ordinal (x : Lst [_]) = x match {
6773 case x : Cons [_] => 0
6874 case Nil => 1
6975 }
7076
71- implicit def mirror [T ]: Mirror .Sum [Lst [T ]] {
77+ implicit def mirror [T ]: Mirror .Sum {
78+ type MirroredType = Lst [T ]
7279 type ElemTypes = (Cons [T ], Nil .type )
7380 } = this .asInstanceOf
7481
7582 case class Cons [T ](hd : T , tl : Lst [T ]) extends Lst [T ]
7683
77- object Cons extends Mirror .Product [Cons [_]] {
84+ object Cons extends Mirror .Product {
85+ type MirroredType = Cons [_]
7886
7987 def apply [T ](x : T , xs : Lst [T ]): Lst [T ] = new Cons (x, xs)
8088
8189 def fromProduct (p : Product ): Cons [_] =
8290 new Cons (productElement[Any ](p, 0 ), productElement[Lst [Any ]](p, 1 ))
8391
84- implicit def mirror [T ]: Mirror .Product [Cons [T ]] {
92+ implicit def mirror [T ]: Mirror .Product {
93+ type MirroredType = Cons [T ]
8594 type ElemTypes = (T , Lst [T ])
8695 type CaseLabel = " Cons"
8796 type ElemLabels = (" hd" , " tl" )
8897 } = this .asInstanceOf
8998 }
9099
91- case object Nil extends Lst [Nothing ] with Mirror .Product [Nil .type ] {
100+ case object Nil extends Lst [Nothing ] with Mirror .Product {
101+ type MirroredType = Nil .type
92102 def fromProduct (p : Product ): Nil .type = Nil
93103
94- implicit def mirror : Mirror .Product [Nil .type ] {
104+ implicit def mirror : Mirror .Product {
105+ type MirroredType = Nil .type
95106 type ElemTypes = Unit
96107 type CaseLabel = " Nil"
97108 type ElemLabels = Unit
@@ -108,12 +119,14 @@ object Lst extends Mirror.Sum[Lst[_]] {
108119
109120case class Pair [T ](x : T , y : T ) // derives Eq, Pickler, Show
110121
111- object Pair extends Mirror .Product [Pair [_]] {
122+ object Pair extends Mirror .Product {
123+ type MirroredType = Pair [_]
112124
113125 def fromProduct (p : Product ): Pair [_] =
114126 Pair (productElement[Any ](p, 0 ), productElement[Any ](p, 1 ))
115127
116- implicit def mirror [T ]: Mirror .Product [Pair [T ]] {
128+ implicit def mirror [T ]: Mirror .Product {
129+ type MirroredType = Pair [T ]
117130 type ElemTypes = (T , T )
118131 type CaseLabel = " Pair"
119132 type ElemLabels = (" x" , " y" )
@@ -129,14 +142,16 @@ object Pair extends Mirror.Product[Pair[_]] {
129142
130143sealed trait Either [+ L , + R ] extends Product with Serializable // derives Eq, Pickler, Show
131144
132- object Either extends Mirror .Sum [Either [_, _]] {
145+ object Either extends Mirror .Sum {
146+ type MirroredType = Either [_, _]
133147
134148 def ordinal (x : Either [_, _]) = x match {
135149 case x : Left [_] => 0
136150 case x : Right [_] => 1
137151 }
138152
139- implicit def mirror [L , R ]: Mirror .Sum [Either [L , R ]] {
153+ implicit def mirror [L , R ]: Mirror .Sum {
154+ type MirroredType = Either [L , R ]
140155 type ElemTypes = (Left [L ], Right [R ])
141156 } = this .asInstanceOf
142157
@@ -148,18 +163,22 @@ object Either extends Mirror.Sum[Either[_, _]] {
148163case class Left [L ](elem : L ) extends Either [L , Nothing ]
149164case class Right [R ](elem : R ) extends Either [Nothing , R ]
150165
151- object Left extends Mirror .Product [Left [_]] {
166+ object Left extends Mirror .Product {
167+ type MirroredType = Left [_]
152168 def fromProduct (p : Product ): Left [_] = Left (productElement[Any ](p, 0 ))
153- implicit def mirror [L ]: Mirror .Product [Left [L ]] {
169+ implicit def mirror [L ]: Mirror .Product {
170+ type MirroredType = Left [L ]
154171 type ElemTypes = L *: Unit
155172 type CaseLabel = " Left"
156173 type ElemLabels = " x" *: Unit
157174 } = this .asInstanceOf
158175}
159176
160- object Right extends Mirror .Product [Right [_]] {
177+ object Right extends Mirror .Product {
178+ type MirroredType = Right [_]
161179 def fromProduct (p : Product ): Right [_] = Right (productElement[Any ](p, 0 ))
162- implicit def mirror [R ]: Mirror .Product [Right [R ]] {
180+ implicit def mirror [R ]: Mirror .Product {
181+ type MirroredType = Right [R ]
163182 type ElemTypes = R *: Unit
164183 type CaseLabel = " Right"
165184 type ElemLabels = " x" *: Unit
@@ -188,28 +207,28 @@ object Eq {
188207 true
189208 }
190209
191- inline def eqlProduct [T ](m : Mirror .Product [T ])(x : Any , y : Any ): Boolean =
210+ inline def eqlProduct [T ](m : Mirror .ProductOf [T ])(x : Any , y : Any ): Boolean =
192211 eqlElems[m.ElemTypes ](0 )(x, y)
193212
194213 inline def eqlCases [Alts ](n : Int )(x : Any , y : Any , ord : Int ): Boolean =
195214 inline erasedValue[Alts ] match {
196215 case _ : (alt *: alts1) =>
197216 if (ord == n)
198217 implicit match {
199- case m : Mirror .Product [`alt`] => eqlElems[m.ElemTypes ](0 )(x, y)
218+ case m : Mirror .ProductOf [`alt`] => eqlElems[m.ElemTypes ](0 )(x, y)
200219 }
201220 else eqlCases[alts1](n + 1 )(x, y, ord)
202221 case _ : Unit =>
203222 false
204223 }
205224
206- inline def derived [T ](implicit ev : Mirror [T ]): Eq [T ] = new Eq [T ] {
225+ inline def derived [T ](implicit ev : MirrorOf [T ]): Eq [T ] = new Eq [T ] {
207226 def eql (x : T , y : T ): Boolean =
208227 inline ev match {
209- case m : Mirror .Sum [T ] =>
228+ case m : Mirror .SumOf [T ] =>
210229 val ord = m.ordinal(x)
211230 ord == m.ordinal(y) && eqlCases[m.ElemTypes ](0 )(x, y, ord)
212- case m : Mirror .Product [T ] =>
231+ case m : Mirror .ProductOf [T ] =>
213232 eqlElems[m.ElemTypes ](0 )(x, y)
214233 }
215234 }
@@ -248,7 +267,7 @@ object Pickler {
248267 case _ : (alt *: alts1) =>
249268 if (ord == n)
250269 implicit match {
251- case m : Mirror .Product [`alt`] => pickleElems[m.ElemTypes ](0 )(buf, x)
270+ case m : Mirror .ProductOf [`alt`] => pickleElems[m.ElemTypes ](0 )(buf, x)
252271 }
253272 else pickleCases[alts1](n + 1 )(buf, x, ord)
254273 case _ : Unit =>
@@ -266,7 +285,7 @@ object Pickler {
266285 case _ : Unit =>
267286 }
268287
269- inline def unpickleCase [T , Elems <: Tuple ](buf : mutable.ListBuffer [Int ], m : Mirror .Product [T ]): T = {
288+ inline def unpickleCase [T , Elems <: Tuple ](buf : mutable.ListBuffer [Int ], m : Mirror .ProductOf [T ]): T = {
270289 inline val size = constValue[Tuple .Size [Elems ]]
271290 inline if (size == 0 )
272291 m.fromProduct(EmptyProduct )
@@ -282,30 +301,30 @@ object Pickler {
282301 case _ : (alt *: alts1) =>
283302 if (ord == n)
284303 implicit match {
285- case m : Mirror .Product [`alt` & T ] =>
304+ case m : Mirror .ProductOf [`alt` & T ] =>
286305 unpickleCase[`alt` & T , m.ElemTypes ](buf, m)
287306 }
288307 else unpickleCases[T , alts1](n + 1 )(buf, ord)
289308 case _ : Unit =>
290309 throw new IndexOutOfBoundsException (s " unexpected ordinal number: $ord" )
291310 }
292311
293- inline def derived [T ](implicit ev : Mirror [T ]): Pickler [T ] = new {
312+ inline def derived [T ](implicit ev : MirrorOf [T ]): Pickler [T ] = new {
294313 def pickle (buf : mutable.ListBuffer [Int ], x : T ): Unit =
295314 inline ev match {
296- case m : Mirror .Sum [T ] =>
315+ case m : Mirror .SumOf [T ] =>
297316 val ord = m.ordinal(x)
298317 buf += ord
299318 pickleCases[m.ElemTypes ](0 )(buf, x, ord)
300- case m : Mirror .Product [T ] =>
319+ case m : Mirror .ProductOf [T ] =>
301320 pickleElems[m.ElemTypes ](0 )(buf, x)
302321 }
303322 def unpickle (buf : mutable.ListBuffer [Int ]): T =
304323 inline ev match {
305- case m : Mirror .Sum [T ] =>
324+ case m : Mirror .SumOf [T ] =>
306325 val ord = nextInt(buf)
307326 unpickleCases[T , m.ElemTypes ](0 )(buf, ord)
308- case m : Mirror .Product [T ] =>
327+ case m : Mirror .ProductOf [T ] =>
309328 unpickleCase[T , m.ElemTypes ](buf, m)
310329 }
311330 }
@@ -341,7 +360,7 @@ object Show {
341360 Nil
342361 }
343362
344- inline def showCase (x : Any , m : Mirror .Product [_]): String = {
363+ inline def showCase (x : Any , m : Mirror .ProductOf [_]): String = {
345364 val label = constValue[m.CaseLabel ]
346365 showElems[m.ElemTypes , m.ElemLabels ](0 )(x).mkString(s " $label( " , " , " , " )" )
347366 }
@@ -351,21 +370,21 @@ object Show {
351370 case _ : (alt *: alts1) =>
352371 if (ord == n)
353372 implicit match {
354- case m : Mirror .Product [`alt`] =>
373+ case m : Mirror .ProductOf [`alt`] =>
355374 showCase(x, m)
356375 }
357376 else showCases[alts1](n + 1 )(x, ord)
358377 case _ : Unit =>
359378 throw new MatchError (x)
360379 }
361380
362- inline def derived [T ](implicit ev : Mirror [T ]): Show [T ] = new {
381+ inline def derived [T ](implicit ev : MirrorOf [T ]): Show [T ] = new {
363382 def show (x : T ): String =
364383 inline ev match {
365- case m : Mirror .Sum [T ] =>
384+ case m : Mirror .SumOf [T ] =>
366385 val ord = m.ordinal(x)
367386 showCases[m.ElemTypes ](0 )(x, ord)
368- case m : Mirror .Product [T ] =>
387+ case m : Mirror .ProductOf [T ] =>
369388 showCase(x, m)
370389 }
371390 }
0 commit comments