Ich versuche, ein Shapeless
Makro von innen quasiquote
mit aufzurufen, Scala
und bekomme nicht das, was ich gerne hätte.
Mein Makro gibt keine Fehler zurück, erweitert sich jedoch nicht Witness(fieldName)
inWitness.Lt[String]
val implicits = schema.fields.map { field =>
val fieldName:String = field.name
val fieldType = TypeName(field.valueType.fullName)
val in = TermName("implicitField"+fieldName)
val tn = TermName(fieldName)
val cc = TermName("cc")
q"""implicit val $in = Field.apply[$className,$fieldType](Witness($fieldName), ($cc: $className) => $cc.$tn)"""
}
Hier ist meine Field
Definition:
sealed abstract class Field[CC, FieldName] {
val fieldName: String
type fieldType
// How to extract this field
def get(cc : CC) : fieldType
}
object Field {
// fieldType is existencial in Field but parametric in Fied.Aux
// used to explict constraints on fieldType
type Aux[CC, FieldName, fieldType_] = Field[CC, FieldName] {
type fieldType = fieldType_
}
def apply[CC, fieldType_](fieldWitness : Witness.Lt[String], ext : CC => fieldType_) : Field.Aux[CC, fieldWitness.T, fieldType_] =
new Field[CC, fieldWitness.T] {
val fieldName : String = fieldWitness.value
type fieldType = fieldType_
def get(cc : CC) : fieldType = ext(cc)
}
}
In diesem Fall sieht das von mir generierte Implizit wie folgt aus:
implicit val implicitFieldname : Field[MyCaseClass, fieldWitness.`type`#T]{
override type fieldType = java.lang.String
}
Wenn es außerhalb von a definiert worden quasiquote
wäre, würde es etwas erzeugen wie:
implicit val implicitFieldname : Field.Aux[MyCaseClass, Witness.Lt[String]#T, String] = ...
Gibt es etwas, das getan werden kann?
$in
( für die meiner Meinung nach die Verwendung erforderlich istConstantType
)?q"""implicit val $in : Field.Aux[$className, Witness.Lt[String]#T, String] = Field.apply[$className,$fieldType](Witness($fieldName), ($cc: $className) => $cc.$tn)"""
ConstantType
). Haben Sie zufällig ein vollständiges Arbeitsbeispiel?Antworten:
Dies ist meine Arbeitslösung mit Makroanmerkungen im alten Stil.
Es kann sicher mit besseren Quasiquoten verbessert werden, aber mein Ziel war es, etwas so sauberes wie möglich zu zeigen.
Es kann verwendet werden als:
Dies erzeugt ein
MyCaseClass
Begleitobjekt mit erforderlichenFields
Implikationen:Wie bereits erwähnt, ist es ohne ein vollständiges Arbeitsbeispiel ziemlich schwierig, eine vollständige Antwort zu schreiben.
quelle