En Haskell, il existe pas de qui prennent plus d'un paramètre. Toutes les fonctions prennent exactement un paramètre.
Donc si vous avez une fonction comme add :: Int -> Int -> Int
alors c'est en fait l'abréviation de add :: Int -> (Int -> Int)
.
Pourquoi les parenthèses sont-elles importantes ? Parce qu'elles montrent comment ce concept fonctionne. Si nous avons cette fonction add
nous pouvons alors créer une application fonctionnelle avec par exemple 14
alors nous construisons une nouveau fonction, comme :
add14 :: Int -> Int
add14 = add 14
donc cela signifie que nous avons maintenant une fonction qui prend à nouveau un (ici un Int
), et maintenant il va produire un autre Int
il le fait en lui ajoutant 14, donc add14 25
aura pour résultat 39
.
Si vous écrivez add 14 25
ce qui est donc no une application de fonction avec deux paramètres, ce que vous avez réellement écrit est :
-- add 14 25 is equivalent to
(add 14) 25
Vous faites donc d'abord un appel avec 14
et vous faites un appel avec la fonction qui en découle, et 25
comme paramètre.
Pourquoi est-ce important ? Parce que cela signifie que si vous écrivez ainsi
calculate = f 1
cela signifie que votre f 1
construit une fonction, une fonction de signature Int -> (Int -> Int)
. Création de paramètres dans l'en-tête de calculate
et de les ajouter à la fin de f 1
Cela n'a donc aucun sens : vous avez déjà construit une fonction qui prend ces paramètres de toute façon. Cela ne fait donc qu'introduire du bruit.
En calcul lambda , la règle de réécriture où l'on réécrit λ x . f x à juste f est (et vice versa) est appelé η-conversion [wiki] . En Haskell, cela se résume à la réécriture :
f x = g x
à :
f = g
Les opérateurs ne sont pas différents. En fait, si vous écrivez a + b
en Haskell, vous avez écrit (+) a b
avec (+)
une fonction, ou plus verbeux ((+) a) b
.
El f
dans la clause where :
f a b c = a + b
peut par exemple être converti en :
f = (.) ((.) const) (+)