web-dev-qa-db-fra.com

Idiomes de composition de fonction Haskell (.) Et d'application de fonction ($): utilisation correcte

J'ai lu Real World Haskell, et je m'approche de la fin, mais une question de style me tergiverse en ce qui concerne le (.) et ($) les opérateurs.

Lorsque vous écrivez une fonction qui est une composition d'autres fonctions, vous l'écrivez comme:

f = g . h

Mais quand vous appliquez quelque chose à la fin de ces fonctions, je l'écris comme ceci:

k = a $ b $ c $ value

Mais le livre l'écrirait ainsi:

k = a . b . c $ value

Maintenant, pour moi, ils semblent fonctionnellement équivalents, ils font exactement la même chose à mes yeux. Cependant, plus je regarde, plus je vois de gens écrire leurs fonctions de la même manière que le livre: composez avec (.) d'abord et ensuite seulement à la fin utiliser ($) pour ajouter une valeur pour évaluer le lot (personne ne le fait avec de nombreuses compositions en dollars).

Y a-t-il une raison d'utiliser la méthode des livres qui est bien meilleure que d'utiliser tous les ($) symboles? Ou y a-t-il ici une meilleure pratique que je ne reçois pas? Ou est-ce superflu et je ne devrais pas du tout m'en inquiéter?

121
Robert Massaioli

Je suppose que je peux répondre à cette question par l'autorité.

Y a-t-il une raison d'utiliser la méthode des livres qui est bien meilleure que d'utiliser tous les symboles ($)?

Il n'y a pas de raison particulière. Bryan et moi préférons réduire le bruit de ligne. . est plus silencieux que $. Par conséquent, le livre utilise le f . g . h $ x syntaxe.

143
Don Stewart

Ils sont en effet équivalents: Gardez à l'esprit que le $ L'opérateur ne fait rien. f $ x correspond à f x. Le but de $ est son comportement de fixité: priorité associative à droite et minimale. Suppression de $ et en utilisant des parenthèses pour le regroupement au lieu de la priorité des infixes, les extraits de code ressemblent à ceci:

k = a (b (c (value)))

et

k = (a . b . c) value

La raison de préférer le . version sur $ la version est la même raison de préférer les deux à la version très entre parenthèses ci-dessus: attrait esthétique.

Cependant, certains pourraient se demander si l'utilisation d'opérateurs infixes au lieu de parenthèses est basée sur une envie subconsciente d'éviter toute ressemblance possible avec LISP (je plaisante ... je pense?).

52
C. A. McCann

J'ajouterais cela dans f . g $ x, f . g est une unité syntaxique significative.

Pendant ce temps à f $ g $ x, f $ g n'est pas une unité significative. Une chaîne de $ est sans doute plus impératif - premier obtenir le résultat de g de x, ensuite faire f pour , alors faire foo, alors etc.

Pendant ce temps, une chaîne de . est sans doute plus déclaratif, et dans un certain sens plus proche d'une vue centrée sur le flux de données - composez une série de fonctions, et finalement appliquez-les à quelque chose.

37
sclv

Pour moi, je pense que la réponse est (a) la propreté, comme Don a dit ; et (b) je trouve que lorsque je modifie du code, ma fonction peut se retrouver dans un style sans point, et alors tout ce que j'ai à faire est de supprimer le dernier $ au lieu de revenir en arrière et de tout changer. Un point mineur, certes, mais une subtilité.

18

Il y a une discussion intéressante sur cette question sur ce fil haskell-cafe . Apparemment, il existe un point de vue minoritaire selon lequel la bonne associativité de $ est "tout simplement faux" , et en choisissant f . g . h $ x plus de f $ g $ h $ x est un moyen de contourner le problème.

13
Travis Brown

C'est juste une question de style. Cependant, la façon dont le livre le fait est plus logique pour moi. Il compose toutes les fonctions, puis l'applique à la valeur.

Votre méthode a l'air étrange et la dernière $ n'est pas nécessaire.

Cependant, cela n'a vraiment pas d'importance. À Haskell, il existe généralement de très nombreuses façons de faire la même chose.

3
Zifre

Je sais que c'est une très vieille question, mais je pense qu'il y a une autre raison à cela qui n'a pas été mentionnée.

Si vous déclarez une nouvelle fonction sans point f . g . h, la valeur que vous transmettez sera automatiquement appliquée. Cependant, si vous écrivez f $ g $ h, ça ne marchera pas.

Je pense que la raison pour laquelle l'auteur préfère la méthode de composition est qu'elle conduit à une bonne pratique de création de fonctions.

0
hackeryarn