Wirklich, der Grund ist wahrscheinlich nur, dass es <$>
und <*>
ermöglicht, eine Rangfolge Ebene zu teilen. Wir wollen auf jeden Fall <*>
wie
Linksassoziativität so Zeug zu
Prelude> foldr <$> [(+),(*)] <*> [0,1] <*> [[1,2,3], [4,5,6]]
[6,15,7,16,0,0,6,120]
Werke, und das macht auch die richtige Art und Weise <$>
zu verhalten, auch wenn es nicht eine höhere Priorität hat. Tatsächlich ist die Verkettung von mehreren <$>
Operatoren mit Links-Assoziativität nicht sehr nützlich.
Allerdings wäre es auch nicht sehr nützlich mit Rechts-Assoziativität. Wie chepner kommentierte, ist es tatsächlich ein bisschen komisch, dass $
rechtsassoziativ ist. Sicher, das ermöglicht Schreibzusammensetzungen wie
Prelude> sum $ map (+3) $ take 19 $ cycle [4..7]
160
aber dann könnte dies ebenso wie die wohl eleganter geschrieben werden
Prelude> sum . map (+3) . take 19 . cycle $ [4..7]
160
(elegantere sage ich, weil hier die Berechnung Kette analysiert wird als eine einzige funktionale Pipeline, anstatt Imperativ-Stil “ dies tun, dann das, dann ... ”). Dank der Funktorgesetze kann dies genauso mit <$>
und .
wie mit $
und .
erfolgen.
Der einzige Grund, warum Sie die Mehrfach- $
Stil bevorzugen könnte, ist, dass es Infix Ausdrücke in der Pipeline ermöglicht, vielleicht die häufigste Beispiel dafür ist Objektiv-Updates (die mit dem blätterte typischerweise geschrieben &
, aber das Prinzip ist das gleiche): Dieses
Prelude Control.Lens> [4..7] & ix 1+~9 & ix 2*~8
[4,14,48,7]
funktioniert, weil $
und &
sehr niedrige Priorität haben, ziemlich viel niedriger als jeder Infixoperator.Das ist nicht der Fall für <$>
so können Sie nicht
Prelude Control.Lens> ix 1+~9 <$> [[4..8], [5..9]]
<interactive>:23:1: error:
Precedence parsing error
cannot mix ‘+~’ [infixr 4] and ‘<$>’ [infixl 4] in the same infix expression
In einem solchen Fall tun, Sie Notwendigkeit einige Klammern verwenden sowieso, und dann könnten Sie auch tun es mit den auch Low-Vorrang Zusammensetzung Operatoren von Control.Category
:
Prelude Control.Lens Control.Category> (ix 1+~9 >>> ix 2*~8) <$> [[4..8], [5..9]]
[[4,14,48,7,8],[5,15,56,8,9]]
oder mit Pars um jeden Aktualisierungs:
Prelude Control.Lens> (ix 1+~9) . (ix 2*~8) <$> [[4..8], [5..9]]
[[4,14,48,7,8],[5,15,56,8,9]]
Funktion Anwendung ist von Natur aus links- assoziativ; eine bessere Frage wäre, warum ist '$' rechtsassoziativ? – chepner
Außerdem ist "fmap" besser als Funktion * Heben * und nicht als Funktionsanwendung gedacht. Sobald 'fmap' die angehobene Funktion zurückgibt, wird sie wie jede andere Funktion angewendet; keine spezielle Anwendung erforderlich. – chepner