784 votes

Quelle est la différence entre . (point) et $ (signe du dollar) ?

Quelle est la différence entre le point (.) et le symbole du dollar ($) ?

D'après ce que je comprends, il s'agit dans les deux cas d'un sucre syntaxique permettant de ne pas utiliser de parenthèses.

1337voto

Michael Steele Points 6064

Le site $ permet d'éviter les parenthèses. Tout ce qui apparaît après lui aura la priorité sur tout ce qui le précède.

Par exemple, disons que vous avez une ligne qui se lit comme suit :

putStrLn (show (1 + 1))

Si vous voulez vous débarrasser de ces parenthèses, n'importe laquelle des lignes suivantes fera la même chose :

putStrLn (show $ 1 + 1)
putStrLn $ show (1 + 1)
putStrLn $ show $ 1 + 1

L'objectif principal de la . ne sert pas à éviter les parenthèses, mais à enchaîner les fonctions. Il vous permet de lier la sortie de ce qui apparaît à droite à l'entrée de ce qui apparaît à gauche. Cela permet généralement de réduire le nombre de parenthèses, mais fonctionne différemment.

Reprenons le même exemple :

putStrLn (show (1 + 1))
  1. (1 + 1) n'a pas d'entrée, et ne peut donc pas être utilisé avec la fonction . opérateur.
  2. show peut prendre un Int et retourner un String .
  3. putStrLn peut prendre un String et retourner un IO () .

Vous pouvez enchaîner show a putStrLn comme ça :

(putStrLn . show) (1 + 1)

Si cela fait trop de parenthèses à votre goût, vous pouvez vous en débarrasser avec la fonction $ opérateur :

putStrLn . show $ 1 + 1

72 votes

En fait, puisque + est aussi une fonction, ne pourriez-vous pas le faire préfixer puis le composer également, comme ` putStrLn . show . (+) 1 1 ` Non pas que ce soit plus clair, mais je veux dire... vous pourriez, non ?

9 votes

@CodexArcanum Dans cet exemple, quelque chose comme putStrLn . show . (+1) $ 1 seraient équivalentes. Vous avez raison de dire que la plupart (tous ?) des opérateurs infixes sont des fonctions.

0 votes

Après avoir vu putStrLn $ show $ 1 + 1 Je pense honnêtement, $ doit être remplacé par un caractère de poids léger. Je ne peux pas penser à un personnage pour le moment, parce qu'ils sont tous utilisés, mais un personnage va émerger.

209voto

Ganesh Sittampalam Points 17695

Ils ont différents types et différentes définitions :

infixr 9 .
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x = f (g x)

infixr 0 $
($) :: (a -> b) -> a -> b
f $ x = f x

($) est destiné à remplacer l'application normale de la fonction mais à une précédence différente pour aider à éviter les parenthèses. (.) sert à composer deux fonctions ensemble pour en faire une nouvelle.

Dans certains cas, ils sont interchangeables, mais ce n'est pas vrai en général. L'exemple typique où ils le sont est le suivant :

f $ g $ h $ x

\==>

f . g . h $ x

En d'autres termes, dans une chaîne de $ tous sauf le dernier peuvent être remplacés par .

2 votes

Et si x était une fonction ? Pouvez-vous alors utiliser . comme le dernier ?

3 votes

@richizy si vous postulez vraiment. x dans ce contexte, alors oui - mais alors le "final" s'appliquerait à quelque chose d'autre que x . Si vous ne postulez pas x alors ce n'est pas différent de x étant une valeur.

135voto

Martijn Points 3955

Notez également que ($) es la fonction d'identité spécialisée dans les types de fonctions . La fonction d'identité ressemble à ceci :

id :: a -> a
id x = x

Alors que ($) ressemble à ça :

($) :: (a -> b) -> (a -> b)
($) = id

Notez que j'ai intentionnellement ajouté des parenthèses supplémentaires dans la signature du type.

Utilisations de ($) peut généralement être éliminé en ajoutant des parenthèses (sauf si l'opérateur est utilisé dans une section). Par exemple : f $ g x devient f (g x) .

Utilisations de (.) sont souvent un peu plus difficiles à remplacer ; ils nécessitent généralement un lambda ou l'introduction d'un paramètre de fonction explicite. Par exemple :

f = g . h

devient

f x = (g . h) x

devient

f x = g (h x)

J'espère que cela vous aidera !

0 votes

"Notez que j'ai intentionnellement ajouté des parenthèses supplémentaires dans la signature du type." Je suis confus... pourquoi as-tu fait ça ?

9 votes

@MateenUlhaq Le type de ($) est (a -> b) -> a -> b, ce qui est identique à (a -> b) -> (a -> b), mais les parenthèses supplémentaires ajoutent ici un peu de clarté.

4 votes

Oh, je suppose. Je pensais à une fonction de deux arguments... mais à cause du currying, c'est exactement équivalent à une fonction qui renvoie une fonction.

84voto

softmechanics Points 381

($) permet d'enchaîner des fonctions sans ajouter de parenthèses pour contrôler l'ordre d'évaluation :

Prelude> head (tail "asdf")
's'

Prelude> head $ tail "asdf"
's'

L'opérateur de composition (.) crée une nouvelle fonction sans spécifier les arguments :

Prelude> let second x = head $ tail x
Prelude> second "asdf"
's'

Prelude> let second = head . tail
Prelude> second "asdf"
's'

L'exemple ci-dessus est sans doute illustratif, mais ne montre pas vraiment l'intérêt d'utiliser la composition. Voici une autre analogie :

Prelude> let third x = head $ tail $ tail x
Prelude> map third ["asdf", "qwer", "1234"]
"de3"

Si nous n'utilisons le tiers qu'une seule fois, nous pouvons éviter de le nommer en utilisant un lambda :

Prelude> map (\x -> head $ tail $ tail x) ["asdf", "qwer", "1234"]
"de3"

Enfin, la composition nous permet d'éviter le lambda :

Prelude> map (head . tail . tail) ["asdf", "qwer", "1234"]
"de3"

7 votes

Si le stackoverflow avait une fonction de combinaison, je préférerais la réponse combinant les deux explications précédentes avec l'exemple de cette réponse.

62voto

ellisbben Points 3213

La version courte et douce :

  • ($) appelle la fonction qui est son argument de gauche sur la valeur qui est son argument de droite.
  • (.) compose la fonction qui est son argument de gauche sur la fonction qui est son argument de droite.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X