2012-05-30 14 views
7

Ich habe ein Lambda \x f -> f x, das in einem foldM-Betrieb verwendet wird, wobei x ein Wert und f :: a -> b ist.Haskell-Funktion zum Reverse-Funktionsaufruf

Gibt es eine eingebaute Funktion, die das tut?

Kann ich ersetzen

foldM (\x f -> f x) ... 

mit einigen f'

foldM f' ... 

Ich dachte, dass flip dies tun würde, aber es dauert drei Argumente (flip :: (a -> b -> c) -> b -> a -> c)

Es ist wahrscheinlich ähnlich wie |> in F #.

Antwort

20

Sie können flip id oder flip ($) verwenden (als ($) ist nur eine spezielle id für Funktionen):

Prelude> flip id 3 (+2) 
5 
Prelude> flip ($) 7 (>10) 
False 

Dies ist eine interessante Anwendung von partieller Anwendung: id f x mit f eine Funktion sein, ist nur f x. Offensichtlich ist dies auch das gleiche wie (flip id) x f, also flip id ist die Funktion, die Sie suchen.

Wenn Sie abenteuerlustig sind, versuchen Sie den Typ flip id oder flip ($) manuell abzuleiten. Es macht Spaß :)

+0

Wow, das dauerte ungefähr 5 Minuten mit Papier und Stift, um herauszufinden, wie 'id's' a -> a'-Signatur irgendwie auf 'flip' aufsetzen könnte, was etwas mit' a- erwartet. > b -> c'. Es könnte sich lohnen, das ein wenig zu vertiefen! – Ashe

+1

@Len: Es wird klarer, sobald Sie sehen, dass, wenn ID auf Funktionen angewendet wird, "ID" ist das gleiche wie '($)' –

+0

Das ist sehr wahr! Der "a-ha" -Moment für mich war, zu erkennen, dass ich "a -> b -> c" als das "a -> (b -> c)" sehen sollte, das es ist, und dann das mit "id" übereinstimmte. s 'a' -> a''und fand, dass' a = a '= (b -> c) '- Ich habe zu viel auf die Unterschiede in der Arität geachtet und konnte nicht darüber hinwegkommen. – Ashe

8

Ja, es heißt flip :: (a -> b -> c) -> b -> a -> c, z.B. flip (>) 3 5 == True. Mehr Infos und Quelle zum Thema: flip.

Was Sie wollen, ist einfach die Argumente der Funktion Anwendung umgekehrt, richtig? Nun, da ($) Funktion Anwendung ist, können Sie schreiben flip ($) :: b -> (b -> c) -> c. Lass sehen was passiert. Hier ist die Quelle für die beiden Auftakt-Funktionen:

-- from Hackage: 
($)      :: (a -> b) -> a -> b 
f $ x     = f x 

-- from Hackage: 
flip     :: (a -> b -> c) -> b -> a -> c 
flip f x y    = f y x 

Also, im Grunde, wenn Sie die Typen zusammen, flip ($) wird

flip ($) :: 
    b  -> -- type of x, argument of y and second argument of ($) 
    (b -> c) -> -- type of y, function applied by ($) as its first argument 
    c  -> -- result of the application "y x" 

Wenn Sie folgen Sie den aktuellen Definitionen der Funktionen:

flip ($) = (\f x y -> f y x) ($) -- from flip's def. 
     = \x y -> ($) y x   -- partial application 
     = y x      -- from ($)'s def. 
Verwandte Themen