Haskell: a - a - ... - b bis [a] - b [duplizieren]

8

Ich versuche, die folgende Karte als Haskell-Funktion auszudrücken:

Bei zwei Typen a, b wird die Familie der Funktionen F(a, b) bestehend aus Funktionen des Typs

berücksichtigt %Vor%

mit n Wiederholungen von a , wobei n eine Ganzzahl größer als Null ist. Ich möchte jede Funktion f in F(a, b) einer Funktion f' :: [a] -> b zuordnen, also f x1 x2 ... xr = f' [x1, ..., xr] , wobei r kleiner ist als die Anzahl der Argumente, die f benötigt (also ich suche die Funktion listify :: F(a, b) -> ([a] -> b) ). Wenn mehr Elemente vorhanden sind, als f Argumente akzeptiert, sollten die zusätzlichen Elemente verworfen werden:

%Vor%

Wenn darüber hinaus die leere Liste übergeben wird, ist jeder Wert akzeptabel.

Ich bin natürlich in der Lage, diese Map für Funktionen mit einer festen Anzahl von Argumenten zu implementieren (zum Beispiel: listify :: (a -> a -> b) -> ([a] -> b) , etc.), aber ich konnte keine Möglichkeit finden, eine Funktion zu schreiben, die dies für alle tut f in F(a, b) gleichzeitig. Obwohl Template Haskell wahrscheinlich in der Lage ist, mir die richtigen Werkzeuge zur Verfügung zu stellen, interessiert mich eine solche Lösung nicht. Ich möchte etwas pure "Art Magie" finden, um es zu tun.

Weiß jemand, ob das überhaupt möglich ist? Kann mir jemand vielleicht in die richtige Richtung zeigen? Oder ist das ein bekanntes "Problem", das Milliarden Mal gelöst wurde und ich einfach keine Lösung finden kann?

    
morris 20.11.2015, 20:16
quelle

2 Antworten

9

Wir müssen hier nur unser Gift aussuchen. Wenn wir weniger sichere Pragmas verwenden, können wir mehr Rückschlüsse ziehen und umgekehrt; Es gibt eine Reihe von Kombinationen.

Zuerst : verwendet überlappende Instanzen, hat Nicht-Funktionen als Basisfall, kann aber nicht mit polymorphen a -Typen umgehen:

%Vor%

Second : Verwendet überlappende Instanzen, hat Funktionen als Basisfall, kann mit polymorphen Typen umgehen:

%Vor%

Third : verwendet inkohärente Instanzen, hat Werte im Basisfall, kann mit polymorphen Typen umgehen:

%Vor%

Vierter : verwendet geschlossene Typfamilien mit UndecidableInstances als Helfer für die Instanzauflösung, hat Werte im Basisfall und kann keine polymorphen Typen behandeln:

%Vor%

Von der Spitze meines Kopfes aus sind das ungefähr die Varianten, die man in freier Wildbahn sehen kann, außer für INCOHERENT eins, weil das im Bibliothekscode extrem selten ist (aus guten Gründen).

Ich persönlich empfehle die Version mit den geschlossenen Typfamilien, weil UndecidableInstances und Typfamilien bei weitem die am wenigsten kontroversen Spracherweiterungen sind, und sie bieten dennoch eine angemessene Menge an Benutzerfreundlichkeit.

    
András Kovács 20.11.2015, 21:23
quelle
5

Eigentlich ist es ziemlich einfach, erfordert nicht einmal überlappende Instanzen:

%Vor%

Dann können Sie

tun %Vor%

Aber die Notwendigkeit für diese lokalen expliziten Typ-Signaturen zeigt ziemlich genau die Probleme auf, in die Sie geraten.

(Es könnte möglich sein, dieses Problem mit FunctionalDependencies zu beheben, aber zumindest nicht direkt.)

    
leftaroundabout 20.11.2015 20:41
quelle