Pointfree (oder Bibliotheksfunktion) zum Anwenden zweier Funktionen auf eine einzelne Eingabe

8

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.

  1. Ich bin interessiert zu wissen, ob es eine Standardbibliotheksfunktion gibt, die das nicht finden kann.
  2. Aus Neugier möchte ich diese Funktion im Punkt-freien Stil umschreiben, aber ich habe große Schwierigkeiten damit.
bshourd 16.01.2013, 03:21
quelle

3 Antworten

12
  1. 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?).

  2. 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.

    
shachaf 16.01.2013, 03:28
quelle
12
  

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:

%Vor%

Es gibt andere, ähnliche Funktionen, zB die äquivalente Operation für Either , die auf (->) spezialisiert ist, sieht folgendermaßen aus:

%Vor%

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 -> (,) & lt; $ & gt ; f & lt; * & gt; g Dies ist im Wesentlichen eine implizite, inline 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) .

    
C. A. McCann 16.01.2013 03:31
quelle
6

Es gibt tatsächlich einige Möglichkeiten, dies zu tun. Die gebräuchlichste Methode ist die (&&&) -Funktion von Control.Arrow :

zu verwenden %Vor%

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%     
ertes 16.01.2013 04:01
quelle

Tags und Links