Ich verwende immer wieder Lambda-Ausdrücke wie
%Vor%wo ich dieselbe Eingabe auf zwei Funktionen anwende und das Ergebnis in ein Paar kapsle. Ich kann eine Funktion schreiben, die dieses fängt
%Vor% Nun ist der obige Lambda-Ausdruck nur combine f g
. Ich habe zwei Fragen.
Control.Arrow
hat die Funktion (&&&)
dafür. Es hat einen "allgemeineren" Typ, was leider bedeutet, dass Hoogle es nicht findet (vielleicht sollte dies als Fehler in Hoogle betrachtet werden?).
Normalerweise können Sie solche Dinge automatisch mit pointfree
abbilden, die lambdabot
in #haskell
hat als Plugin.
Zum Beispiel:
%Vor% Wo liftM2
mit der (r ->)
Instanz von Monad
hat den Typ (a -> b -> c) -> (r -> a) -> (r -> b) -> r -> c
. Natürlich gibt es viele andere Möglichkeiten, diesen Punkt frei zu schreiben, abhängig davon, welche Primitive du erlaubst.
Ich bin interessiert zu wissen, ob es eine Standard-Bibliotheksfunktion gibt, die das nicht finden kann.
Es ist leicht zu übersehen, wegen der Typklasse, aber schau dir das an Control.Arrow
. Plain Arrow
s kann nicht curiert oder angewendet werden, daher sind die Arrow
-Kombinatoren notwendigerweise punktfrei. Wenn du sie auf (->)
spezialisierst, wirst du folgendes finden:
Es gibt andere, ähnliche Funktionen, zB die äquivalente Operation für Either
, die auf (->)
spezialisiert ist, sieht folgendermaßen aus:
Dies ist das gleiche wie either
.
Aus Neugierde möchte ich diese Funktion im Punkt-freien Stil umschreiben, aber ich habe eine Menge Probleme damit.
Da du eine Eingabe duplizierst, brauchst du eine Möglichkeit, diese pointfree zu machen - die gebräuchlichste Methode ist die Applicative
oder Monad
-Instanz für (->)
, zum Beispiel \f g ->
Dies ist im Wesentlichen eine implizite, inline (,)
& lt; $ & gt ; f & lt; * & gt; g Reader
-Monade, und das Argument, das aufgeteilt wird, ist der "Umgebungs" -Wert. Bei diesem Ansatz wird join f x
zu f x x
, pure
oder return
wird zu const
, fmap
wird zu (.)
und (<*>)
wird zur S Kombinator \f g x -> f x (g x)
.
Es gibt tatsächlich einige Möglichkeiten, dies zu tun. Die gebräuchlichste Methode ist die (&&&)
-Funktion von Control.Arrow
:
Allerdings haben Sie oft mehr Funktionen oder müssen das Ergebnis an eine andere Funktion übergeben. In diesem Fall ist es viel praktischer, den anwendungsspezifischen Stil zu verwenden. Dann
%Vor%wird
%Vor%Wie bereits erwähnt, kann dies mit mehr als einer Funktion verwendet werden:
%Vor%