2013-09-28 9 views
9

Die Zusammensetzung von f und g, das aussieht wieEin gemeinsames Muster Einbeziehung Zusammensetzung von Funktionen ( a b -> f (g a) (g b))

f :. g = \a b -> f (g a) (g b) 

ein Muster, das ich sehr oft in meinem Code finden. Es ähnelt der unären Funktionszusammensetzung, nur f ist binär und ich möchte g auf beide Argumente anwenden, bevor sie an f übergeben werden.

Als ich lambdabot bitte dies zu Punkt freier Form zu konvertieren, erhalte ich die seltsamen Beschwörungs

, die ich lieber nicht in meinem Code, so dass ich am Ende nur explizit das Muster auszuzuschreiben .

Gibt es eine allgemein akzeptierte Möglichkeit, einen Kombinator für diese Situation zu schreiben? Oder bin ich seltsam, dass ich mich in dieser Situation ziemlich oft wiederfinde?

Ich habe kein aktuelles Beispiel, wenn ich es jetzt benutze, da ich nie daran gedacht habe, hier zu fragen, wenn ich es brauche, aber man könnte sich vorstellen, die euklidische Distanzformel sehr sauber zu schreiben, so wie:

distance = sqrt . (+) :. (^2) 
+2

'flip' beseitigt werden könnte:' (g.). f. g' –

Antwort

24

Diese Funktion on im Data.Function Modul aufgerufen wird.

Es wird oft Infix verwendet, wie sqrt . (+) `on` (^2).

+2

Ich kann nicht glauben, dass ich nicht darüber nachgedacht habe! Vielen Dank. – kqr

+0

Ein übliches Beispiel der Verwendung ist 'sortBy (vergleiche \' on \ 'abs) ' –

+0

Ich werde für zukünftige Google Leute jedoch notieren, dass" das Vergleichen von ABS "idiomatischer ist als' '' 'auf' abs' 'vergleichen. Dies funktioniert, weil "comparing = on compare" irgendwo in den Standard-Bibliotheken definiert ist. – kqr

2

Versuchen Sie nicht, es punktefrei zu schreiben. Dies ist ein Beispiel dafür, dass Punktfreiheit häufig nicht so gut lesbar ist.

definieren Sie es einfach so:

(:.) :: (b -> b -> c) -> (a -> b) -> (a -> a -> c) 
infixr 9 (:.) 
f :. g x y = f (g x) (g y) 
+0

Ein Infix-Operator ist hier fraglich, zumal viele ''. ''Oder'.: 'For' (.) Verwenden. (.) ' – jozefg

+0

@jozefg Schießen Sie nicht den Messenger - es ist das Symbol, das das OP in der Frage verwendet. –

+0

@jozefg Ich wählte absichtlich ': .' als eine Parallele zu'.: ', Die in der Tat oft für den Eulenoperator verwendet wird. Ich sehe es als '.:' Nimmt eine Funktion von einem Argument nach links (daher der Punkt) und eine Funktion von zwei Argumenten auf der rechten Seite (daher die Doppelpunkte) - so ': .' sollte eine Funktion von zwei Argumenten nehmen auf der linken Seite und eine Funktion eines Arguments auf der rechten Seite. – kqr

Verwandte Themen