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.