Betrachten Sie den folgenden Haskell-Code.
%Vor% Gibt es eine Möglichkeit, getSeq
in pointfree form zu schreiben?
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?
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
und für Either
ist es
Ein fortgeschrittener Katamorphismus ist der für Listen, die Sie wahrscheinlich schon einmal gesehen haben: foldr
!
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:
[]
behandelt werden muss und der überhaupt keine Argumente benötigt: nur ein Wert vom Typ b
(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:
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% 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:
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.
Tags und Links haskell