Nachweishaltende LUB-Einschränkung für HList

8

Ich denke, ich brauche einen HList, der so eingeschränkt ist, dass alle seine Elemente ein Untertyp eines bestimmten Typs sind. LUBConstraint scheint das zu sein, was ich will, und tatsächlich beschränkt es die Konstruktion eines solchen HLists - aber ich kann nicht sehen, wie ich die Beweise wieder herausbekomme, damit ich (eigentlich , traverse, weil es monadisch sein muss) über die HList und rufen Sie eine Methode (die im LUB-Typ existiert) auf jedem der Elemente auf.

Zusätzlich möchte ich, dass der Typ des HLists, der aus der Polygonzugoperation resultiert, genau der gleiche Typ wie der Typ des Eingabe-HLists ist.

Der Anwendungsfall ist eine Art funktionale "Listener List" - alle Elemente des HList sind "Listener", die über "Ereignisse" benachrichtigt werden müssen, diese akzeptieren oder ablehnen und neue Versionen von sich selbst mit aktualisierten " internen Zustand". Wenn das alles wäre, was ich brauchte, könnte ich einfach eine gewöhnliche unveränderliche Scala-Sammlung verwenden. Aber ich möchte auch direkten typisierten Zugriff auf einzelne Elemente ohne Verwendung von asInstanceOf - daher die Motivation für den Versuch, HList zu verwenden.

    
Robin Green 19.05.2015, 09:40
quelle

1 Antwort

8

Wenn Sie eine Operation ausführen möchten, die Sie für alle Elemente in HList ausführen möchten, sollten Sie einen Wert für die polymorphe Funktion über HList zuordnen. Angenommen, ich habe das folgende Setup:

%Vor%

Nun möchte ich String an jeden dieser Listener senden und die Ergebnisse sammeln. Wenn ich nur einen festen Wert senden wollte, wäre das einfach:

%Vor%

Dies wird entsprechend als Option[FooListener] :: Option[BarListener] :: HNil eingegeben. Wenn ich shapeless-contrib verwende, kann ich dieses HList :

sequenzieren %Vor%

Oder verwenden Sie einfach traverse :

%Vor%

Leider gibt es Einschränkungen, wie polymorphe Funktionswerte definiert werden können, die bedeuten, dass eine partielle Anwendung nicht praktisch ist. Wenn wir also die String , die wir zur Kompilierzeit senden, nicht kennen, ist das viel komplizierter :

%Vor%

Wo wir die Elemente mit der Zeichenfolge gezippt und dann eine polymorphe Funktion zugeordnet haben, die Tupel über das Ergebnis nimmt. Es gibt andere Möglichkeiten, wie Sie dies mit mehr oder weniger dem gleichen Ansatz tun können, aber keiner von ihnen ist fürchterlich klar.

Ein völlig anderer Ansatz besteht darin, die polymorphen Funktionswerte zu überspringen und eine neue Typklasse zu definieren:

%Vor%

Und dann:

%Vor%

Dies ist weniger generisch (es funktioniert nur auf Option , nicht beliebige Anwendungen), aber es erfordert keine zusätzliche Abhängigkeit für die Sequenzierung, und es ist wohl ein bisschen weniger durcheinander als durch Hoops springen, um eine polymorphe Funktion teilweise anzuwenden Wert wegen seltsamer Einschränkungen des Compilers.

    
Travis Brown 19.05.2015, 13:27
quelle

Tags und Links