2017-04-15 5 views
16

Ich habe gerade festgestellt, dass (<$>) eine Festigkeit von infixl 4 hat. Wie kann das sein?

(+1) <$> (/5) <$> [5,10] funktioniert offensichtlich von rechts nach links.

Antwort

18

Nein, <$> ist assoziativ und dies ist in Ihrem Beispiel nicht anders. (+1) <$> (/5) <$> [5,10] wird als ((+1) <$> (/5)) <$> [5,10] gelesen. Dies passiert, weil die Functor Instanz von (->) a ist im Grunde äquivalent zu Funktionszusammensetzung; fmap (+1) (/5) ist äquivalent zu \x -> (x/5)+1, was Ihnen in diesem Fall das gleiche Ergebnis liefert wie das, was Sie mit der Bestellung erhalten würden, von der Sie glauben, dass sie funktioniert, d. H. (+1) <$> ((+5) <$> [5,10]).

Da dies ein wenig verwirrend ist, wenn Sie mehrere Funktionen in einer Zeile anwenden möchten, ist es wahrscheinlich besser für die Lesbarkeit, den normalen Funktionszusammensetzungsoperator hier zu verwenden: (+1) . (/5) <$> [5,10].

+0

Es spielt also keine Rolle, ob es links oder rechts assoziativ ist, was die Semantik betrifft (und Funktoren erfüllen tatsächlich die Funktorgesetze). Ich frage mich, ob die linke Assoziation eine bewußte Wahl war, z.B. aus Leistungsgründen. Es könnte sogar auf diese Weise zufällig oder theoretisch falsch definiert worden sein. – chi

+2

@chi Wenn '(<$>)' richtig assoziativ waren, konnten Sie das 'f <$> x <*> y'-Stilmuster nicht mehr verwenden (weil' (<*>) 'auch rechts assoziativ sein müsste, damit Sie sie zusammen ohne verwenden können Klammern so). Es gibt Leute, die sagen, dass '($)' assoziativ sein sollte, weil man dann etwas wie 'f $ gx $ hy' machen könnte und es wäre äquivalent zu 'f (gx) (hy)' (und I denke, es wäre symmetrisch mit wie '->' ist rechts assoziativ). Natürlich kommt es wirklich auf die Vorliebe an. –

+0

@DavidYoung Ah, richtig. Das macht Sinn, danke. – chi

Verwandte Themen