Quelle est la signification des parenthèses dans les signatures de type Haskell?
Prenez la signature de type de fmap (La Méthode Functor) comme exemple: 
(a -> b) -> f a -> f b
En quoi est-ce différent de la signature de type suivante?
a -> b -> f a -> f b
Y a-t-il même une différence entre ces deux signatures de type?
3 réponses
Oui, il y a une différence, car  le constructeur de type -> est  droit-associatif. En d'autres termes,
a -> b -> f a -> f b
Est équivalent à
a -> (b -> (f a -> f b))
Ce type de signature désigne une fonction qui prend un paramètre de type a et retourne une fonction qui prend un paramètre de type b et retourne une fonction qui prend un paramètre de type f a et renvoie une valeur de type f b.
D'autre part,
(a -> b) -> f a -> f b
Désigne une fonction qui prend un paramètre de type a -> b (c'est à dire une fonction qui prend un paramètre de type a et renvoie une valeur de type b) et retourne une fonction qui prend un paramètre de type f a et renvoie une valeur de type f b.
Voici un exemple artificiel qui illustre la différence entre les deux signatures de type:
f :: (Int -> Bool) -> [Int] -> [Bool]
f = map
g :: Int -> Bool -> [Int] -> [Bool]
g n b = map (\n' -> (n' == n) == b)
λ> let ns = [42, 13, 42, 17]
λ> f (== 42) ns
[True,False,True,False]
λ> g 42 True ns
[True,False,True,False]
λ> g 42 False ns
[False,True,False,True]
Oui
(a -> b) -> ...
Signifie " Étant donné une fonction qui prend a à B...". Alors que, ce
a -> b -> ...
Signifie " Étant donné certains a et certains B..."
Oui, le (a -> b) signifie un argument qui est une fonction avec signature a -> b, alors que a -> b -> ... signifie deux arguments.