2016-04-04 6 views
1

Ich habe den nächsten Code:rekursive Druckfeldname bei Klasse über formlos

trait X 
case class Bar(id: Int) extends X 
case class Foo(id: Int, bar: Bar) extends X 

ich will für Foo mit inneren Klassen alle Felder drucken, die ich für sie formlos verwenden, und erstellen Poly:

object print1 extends Poly1 { 
    implicit def c[K, V](
    implicit wk: Witness.Aux[K]) = { 
    at[FieldType[K, V]](field => { 
     wk.value 
    }) 
    } 
} 

val foo = Foo(1, Bar(10)) 
val fooLgen = LabeledGeneric[Foo] 
pritnln(fooLgen.to(foo).map(print1)) // => 'id::'bar 

Aber wie mit internen Klassen drucken?

Antwort

2

In Ihrem Beispiel erstellen Sie eine HList von Schlüsseln und drucken sie dann. Sie können es rekursiv wie folgt vorgehen:

trait LowerPriorityPrint1 extends Poly1 { 
    implicit def c[K, V](implicit wk: Witness.Aux[K]) = { 
    at[FieldType[K, V]](field => { 
     wk.value 
    }) 
    } 
} 

object print1 extends LowerPriorityPrint1 { 
    implicit def csub[K, V, L <: HList](
    implicit l : LabelledGeneric.Aux[V, L], 
       mapper : Mapper[print1.type, L] 
      ) = { 
    at[FieldType[K, V]](field => { 
     l.to(field).map(print1) 
    }) 
    } 
} 

val foo = Foo(1, Bar(10)) 
val fooLgen = LabelledGeneric[Foo] 
println(fooLgen.to(foo).map(print1)) // => 'idFoo :: 'idBar :: HNil :: HNil 

formlos Arbeiten bei der Kompilierung, so dass Sie die Rekursion auf der Typebene zu schaffen, den Einsatz von implicits. c und cSub gleichzeitig für den gleichen Schlüssel vorhanden sind, können Sie entscheiden, welche zuerst aufgelöst wird, indem Sie die mit niedrigerer Priorität in einem Supertrait

+0

erklären, wie formlos zu verstehen, für welche Methode sollte verwendet werden? und warum ist es unmöglich, LabeledGeneric mit der ursprünglichen 'c'-Methode zu verwenden? – mike

+0

formlos funktioniert zur Kompilierzeit, so dass Sie Rekursion auf der Typenebene erstellen müssen, mit implicits. 'c' und' cSub' existieren zur gleichen Zeit für den gleichen Schlüssel, Sie können entscheiden, welcher zuerst aufgelöst wird, indem Sie denjenigen mit niedrigerer Priorität in einem Supertrait deklarieren. Suchen Sie nach den skalaren impliziten Auflösungsregeln –

+0

ah, habe es vergessen, danke. – mike

Verwandte Themen