Scala implizit für beliebig tiefe Functor-Komposition

8

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.

%Vor%

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:

%Vor%

Gibt es einen Weg, dies zu erreichen?

    
Rui Gonçalves 09.11.2014, 22:48
quelle

2 Antworten

3

Sie können einen impliziten Helfer rekursiv zur Verfügung stellen:

%Vor%     
lmm 10.11.2014, 07:53
quelle
2

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.

%Vor%

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.

%Vor%

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

%Vor%

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.

    
EECOLOR 10.11.2014 12:01
quelle

Tags und Links