2017-03-03 11 views
1

ich meinen Weg durch das erste Haskell Buch und kämpfen mit dem $ Betreiber arbeiten:

Die folgende Zeile funktioniert:

map (>= 16) . take 5 $ iterate (\x -> x^2) 2 

jedoch die folgende doesn‘ t:

map (>= 16) . take 5 (iterate (\x -> x^2) 2) 

Mögliche Ursache: `nehmen‘ zu viele Argumente angewendet wird

Ich sehe das Problem hier nicht. take nimmt ein int und eine Liste. Zu meinem Verständnis lieferte ich beide Argumente.

Was muss ich tun, wenn ich den Operator $ vermeiden möchte?

+2

Das Original ist äquivalent zu '(map (> = 16). Nimm 5) (iterate (\ x -> x^2) 2)'. '.' erwartet, dass seine Operanden Funktionen sind. Sie könnten auch schreiben: map (> = 16) $ take 5 (iterate (\ x -> x^2) 2) '. – Ryan

+1

'map (> = 16). take 5 (iterate (\ x -> x^2) 2) 'bedeutet eigentlich' (map (> = 16)). (nimm 5 (iterate (\ x -> x^2) 2)) 'so' (.) 'wird eine Funktion und eine Liste anstelle von zwei Funktionen übergeben. Denken Sie daran, dass die Anwendung 'f x y z 'eine höhere Priorität hat als jedes Infix wie' + 'oder' .'. – chi

+1

Ich folge oft der Regel: getrennte Funktionen mit '.' und das Argument mit' $ 'Dies würde' map (> = 16) ergeben. nimm 5. Iterieren (^ 2) $ 2' – Ingo

Antwort

7

($) :: (a -> b) -> a -> b Der Operator ist eine Funktion, die einfach ein die niedrigste Priorität hat (infixr 0 nur ($!) and seq have the same priority). Als Ergebnis:

map (>= 16) . take 5 $ iterate (\x -> x^2) 2 

entspricht:

(map (>= 16) . take 5) (iterate (\x -> x^2) 2)

so auch mit Klammern für den linken Operanden als auch.

Es ist eigentlich eine nette Sache über Haskell, dass Sie Betreiber als Gruppierungsmechanismus verwenden können: ($) einfach als ($) f x = f x definiert ist, sondern auch wegen der Tatsache, dass es ein Operator ist, kann es als eine Art und Weise verwendet wird, Klammern zu vermeiden .