Ich versuche, Erweiterungsmethoden zu einer vorhandenen Klasse Elem
in Scala bereitzustellen. Ich möchte aber auch, dass die Operationen für jede M[Elem]
verfügbar sind, solange eine Scalaz Functor
für M
im Bereich ist. Das Verhalten besteht immer darin, die Operation mithilfe von map
auf den Funktor anzuwenden.
Ich möchte weiter gehen und meine Erweiterungsmethoden für beliebig tiefe Funktoren wie List[Option[Elem]]
und Option[Option[Option[Elem]]]
verfügbar machen. Ich konnte eine implizite Angabe von Ops
für die Zusammensetzung von zwei Funktoren schreiben, aber ich konnte sie nicht auf beliebige Schachtelungstiefen verallgemeinern:
Gibt es einen Weg, dies zu erreichen?
Wir können eine Eigenschaft erstellen, die das darstellt, was Sie wollen
%Vor% Beachten Sie, dass X
einer Result[B]
zugeordnet werden kann. X
könnte zu diesem Zeitpunkt alles Mögliche sein.
In der einfachsten Version sagen wir, dass X
gleich A
ist. Das Ergebnis sollte dann Id[B]
sein. Es ist ein Merkmal, um sicherzustellen, dass es eine niedrige Priorität hat.
Beachten Sie, dass Sie nicht nach dem Functor
von Id
fragen müssen.
Die komplexere Version ist, wo X
ein Container ist, für den ein Functor
definiert ist.
Das Ergebnis der Methode deep
ist ein DeepFunctor
für F[X]
. Da wir nichts über X
wissen, fordern wir eine DeepFunctor
für X
an. Dies wird rekursiv nach DeepFunctor
Instanzen suchen, bis identity
erreicht wird.
Ihre Klasse Ops
wird jetzt relativ einfach
Beachten Sie, dass _
jetzt vom Typ A
ist. Wenn Sie auf einen bestimmten Typ einschränken möchten, können Sie A
als A <: SomeType
definieren. Wenn Sie eine implizite Konvertierung unterstützen möchten, können Sie ein zusätzliches implizites Argument ev: A => SomeType
verwenden. Wenn Sie A
zu einem bestimmten Typ machen möchten, können Sie A
entfernen und SomeType
direkt in DeepFunctor
einfügen.