Ist es möglich, pattern-matched Funktionen in Point-Free-Form zu schreiben?

8

Betrachten Sie den folgenden Haskell-Code.

%Vor%

Gibt es eine Möglichkeit, getSeq in pointfree form zu schreiben?

Die Definition von

getSeq ist der Musterübereinstimmung so ähnlich, dass es scheint, dass es eine Möglichkeit gibt, currying oder monads zu verwenden oder etwas, um die Angabe der Parameter i und c zu vermeiden. pointfree.io löst jedoch keine punktefreie Ausgabe für getSeq auf, denke ich aufgrund der Musterübereinstimmung.

Ist es möglich?

    
mherzl 03.10.2017, 23:01
quelle

3 Antworten

16

Insbesondere für rekursive Datentypen mit mehreren Konstruktoren ist es oft nützlich, einen Katamorphismus zu definieren, eine Möglichkeit, eine Datenstruktur zusammenzufalten, wenn für jeden der möglichen Konstruktoren eine Funktion angegeben wird.

Zum Beispiel ist für Bool der Katamorphismus

%Vor%

und für Either ist es

%Vor%

Ein fortgeschrittener Katamorphismus ist der für Listen, die Sie wahrscheinlich schon einmal gesehen haben: foldr !

%Vor%

Normalerweise denken wir nicht so darüber nach (oder zumindest nicht), aber foldr ist ein Katamorphismus: Es handhabt Pattern-Matching und rekursiv dekonstruiert die Liste für Sie, solange Sie " Handler "für Werte, die in den beiden Konstruktoren von [a] gefunden wurden:

  • Ein Fall, in dem [] behandelt werden muss und der überhaupt keine Argumente benötigt: nur ein Wert vom Typ b
  • Ein Fall, mit dem (x:xs) behandelt werden kann. In diesem Fall wird ein Argument für x , den Kopf der Liste, und ein Argument für das Ergebnis des rekursiven Zusammenfaltens des Tails verwendet, ein Wert vom Typ b .

Eine Katamorphose ist für einen Typ mit nur einem Konstruktor weniger aufregend, aber wir können einen für Ihren Keypress -Typ leicht definieren:

%Vor%

In gewisser Weise erlaubt die Katamorphose, den Mustervergleichsteil der Funktionsdefinition wegzuspulen, danach können Sie einfach mit Funktionen arbeiten, die den darunterliegenden Datentyp nicht mehr direkt berühren müssen.

Nachdem Sie diese allgemein nützliche Funktion einmal definiert haben, können Sie sie mehrmals verwenden, um eine beliebige punktefreie Funktion zu implementieren, die Ihr Herz begehrt. In Ihrem Fall könnten Sie einfach

schreiben %Vor%     
amalloy 04.10.2017, 00:32
quelle
12

Wie geschrieben, nein. Aber Sie können das reparieren, wenn Sie wollen:

%Vor%

Dann

%Vor%

und das kann in

konvertiert werden %Vor%     
dfeuer 03.10.2017 23:47
quelle
5

Sie können es nicht ohne ein bisschen boilerplate tun, aber lens kann dieses Muster für Sie generieren, also ist es wahrscheinlich so nah, wie Sie bekommen werden.

Wenn makePrisms von Control.Lens.TH verwendet wird, wird Iso generiert, was im Wesentlichen eine erstklassige Musterübereinstimmung für einen einzelnen Konstruktor-Datentyp ist. Praktischerweise sind Iso s bidirektional, also können Sie view sie (um Werte herauszuholen, wie Mustervergleich) und review sie (um einen Wert wieder einzufügen, wie der Konstruktor normalerweise verwendet).

Mit makePrisms und view ist es möglich, getSeq Punktlos zu schreiben:

%Vor%

Ist das besser? Keine Ahnung. Die Musterübereinstimmung in deinem Code sieht für mich gut aus, aber wenn du lens sowieso schon benutzt, könnte diese Version für dich angenehmer sein.

    
Alexis King 03.10.2017 23:47
quelle

Tags und Links