2012-01-13 4 views

Répondre

7

Eh bien, f1 . f2 x est la composition de f1 et f2 x. Vous voulez probablement dire (f1 . f2) x ou, de manière équivalente, f1 . f2 $ x; c'est-à-dire la composition de f1 et f2, appliquée à x.

La réponse peut être trouvée en regardant les types:

($) :: (a -> b) -> a -> b 
(.) :: (b -> c) -> (a -> b) -> a -> c 

Simplement, ($) applique une fonction à son argument, et (.) ses deux arguments. Les deux chaînes

f . g . h $ x 

et

f $ g $ h $ x 

sont équivalentes; le premier est généralement préféré parce qu'il est plus facile de refactoriser la composition dans sa propre fonction avec couper-coller, mais ce n'est pas une préférence universelle. C'est aussi un peu plus bas sur le bruit visuel.

En effet, ($) est identique à id, la fonction identité; il retourne juste la fonction qui lui est donnée. C'est seulement utile en raison de la très faible priorité de l'opérateur (la plus faible, en fait) qui lui est donnée.

+1

Je dirais que '($)' est aussi utile (ou du moins cool) pour faire des choses comme 'map ($ 3) [(+5), (* 2), (soustraire 4)]' –

+0

Je n'y ai jamais pensé auparavant, mais vous pouvez probablement faire map (\ 'id \' 3) [(+5), (* 2), (soustraire 4)] 'aussi! :) – Rotsor

6

Ni ($) ni (.) ne font quelque chose de spécial pour "lier une expression". Ce ne sont que des opérateurs comme les autres. Tout ce que vous devez savoir, c'est ce qu'ils sont définis et quelles sont leurs fixités. Pour la première:

infixr 0 $ 

f $ x = f x 

Il est donc l'application de la fonction, avec une priorité très faible et droit associativité. Donc, si vous avez f x $ g y z cela signifie (f x) (g y z) ce qui équivaut à seulement f x (g y z). Il est utilisé pour éviter les parenthèses, surtout.

Pour la seconde:

infixr 9 . 

(.) f g x = f (g x) 

Cela ressemble au début, mais (.) fonctionne sur deux fonctions, pas une fonction et un argument, et a priorité très élevé. Donc, si vous avez (f x . g y) z cela signifie (f x) ((g y) z) ce qui équivaut à seulement f x (g y z). La principale différence est qu'avec (.) vous pouvez enchaîner plusieurs fonctions ensemble, comme f1 . f2 . f3, tandis qu'avec ($) vous pouvez seulement appliquer plus de fonctions à un résultat.Ainsi, dans une expression comme f x $ g y $ h z, si vous décidez de remplacer une seule valeur z par une liste complète de valeurs, vous ne pouvez pas écrire map (f x $ g y $ h) zs car les fonctions à appliquer dans l'expression entre parenthèses ne sont pas remplies. Si vous écrivez quelque chose comme f x . g y . h $ z, vous pouvez supprimer uniquement l'application de fonction finale et obtenir map (f x . g y . h) zs et cela fonctionnera.

Questions connexes