Welche Darstellung möchten Sie für F
? Sie könnten sagen, es sollte HNil
sein, aber die x
ist nicht sichtbar außerhalb des Körpers der Klasse, so macht Shapeless die Entscheidung, keine Instanz überhaupt bereitzustellen. Dies ist "nur" eine Designentscheidung - aus meiner Sicht die richtige, aber man kann sich leicht vorstellen, dass Shapeless die HNil
Instanz für Ihre Klasse liefert.
Es wäre auch relativ einfach sein, eigene Instanz zu definieren, für F
, was möglich ist, weil Generic
nur eine andere Art Klasse:
import shapeless._
class F(x: Int)
object F {
implicit val genericF: Generic.Aux[F, HNil] = new Generic[F] {
type Repr = HNil
def from(r: HNil): F = new F(0)
def to(t: F): HNil = HNil
}
}
Als eine andere Antwort Notizen, können Sie sich Shapeless eine Instanz zu schaffen Sie, indem Sie Ihre Klasse in eine Fallklasse ändern. Das ist nicht der einzige Weg, wenn auch-Sie auch den Konstruktor Parameter auf einen val
ändern könnte oder einfach entfernen:
scala> class F(val x: Int)
defined class F
scala> shapeless.Generic[F]
res0: shapeless.Generic[F]{type Repr = shapeless.::[Int,shapeless.HNil]} = [email protected]
scala> class F()
defined class F
scala> shapeless.Generic[F]
res1: shapeless.Generic[F]{type Repr = shapeless.HNil} = [email protected]
Sie könnten nicht der Parameter machen eine var
oder die Klasse abstrakt machen, aber (es sei denn, es war versiegelt und Fall Klassen- oder Objektimplementierungen). Oder Sie könnten das, aber dann müssten Sie Ihre eigenen Instanzen erneut definieren, und Sie würden den Vertrag in der Generic
Dokumentation brechen, die besagt, dass der charakterisierte Typ ein "unveränderlicher Datentyp sein sollte, der einen kanonischen Weg hat Instanzen erstellen und dekonstruieren ".
Soweit ich weiß, die genauen Details, welche Arten von Vereinbarungen der Klassendefinitionen Generic
Instanzen wird nirgendwo dokumentiert (und the source ist nicht leicht zu lesen), aber es ist ziemlich einfach, die Grenzen zu testen, die Sie sind daran interessiert, bestimmte Fälle in der REPL auszuprobieren.
Ich bin überrascht über die downvotes. Ich habe diese Frage hauptsächlich gestellt, um die aufschlussreiche Antwort von Travis Brown zu finden. –
Einverstanden-es ist eine vollkommen vernünftige Frage aus meiner Sicht. –