Ich versuche ein Shapeless
Makro von innerhalb einer quasiquote
mit Scala
zu nennen und ich bekomme nicht, was ich gerne bekommen würde.Wie man Shapeless in einer Quasiquote benutzt?
Mein Makro Rückkehr keine Fehler, aber es ist nicht erweitern Witness(fieldName)
in Witness.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 wird die implizite ich generieren sieht aus wie :
implicit val implicitFieldname : Field[MyCaseClass, fieldWitness.`type`#T]{
override type fieldType = java.lang.String
}
Wenn es Biene gewesen wäre n definiert außerhalb eines quasiquote
würde es so etwas wie erzeugen:
implicit val implicitFieldname : Field.Aux[MyCaseClass, Witness.Lt[String]#T, String] = ...
Gibt es etwas, das getan werden kann?
Verwenden Sie dies in einer Makroannotation? Haben Sie versucht, eine Typannotation für '$ in' zu erstellen (was ich denke, dass Sie' ConstantType' benötigen)? –
@TravisBrown ja Ich baue das mit einer Makro-Annotation (Macro Paradise). Ich habe versucht, einen Typ wie folgt anzugeben: '' 'q" "" implizite val $ in: Field.Aux [$ className, Witness.Lt [Zeichenfolge] #T, String] = Field.apply [$ className, $ fieldType ] (Witness ($ fieldName), ($ cc: $ className) => $ cc. $ Tn) "" "' '' – Roch
Sie müssen jedoch den spezifischen Feldnamen in der Anmerkung des Typs eingeben (siehe z. B. mein altes Pre Shapeless 2.0 blog post [hier] (https://meta.plasm.us/posts/2013/06/28/singleton-types-for-literals-in-scala/) für ein Beispiel der Verwendung von 'ConstantType'). Haben Sie ein komplettes Arbeitsbeispiel? –