Haskell Language
Syntaxe d'appel de fonction
Recherche…
Introduction
La syntaxe d'appel de la fonction de Haskell, expliquée par des comparaisons avec les langages de style C, le cas échéant. Ceci est destiné aux personnes qui viennent à Haskell à partir d'une formation en langage C.
Remarques
En général, la règle pour convertir un appel de fonction de style C en Haskell, dans n'importe quel contexte (affectation, retour ou incorporé dans un autre appel), consiste à remplacer les virgules de la liste d'arguments de style C par des espaces et à déplacer l'ouverture. parenthèses de l'appel de style C pour contenir le nom de la fonction et ses paramètres.
Si des expressions sont placées entièrement entre parenthèses, ces paires de parenthèses (externes) peuvent être supprimées pour des raisons de lisibilité, car elles n'affectent pas la signification de l'expression.
Il existe d'autres circonstances dans lesquelles les parenthèses peuvent être supprimées, mais cela n'affecte que la lisibilité et la maintenabilité.
Parenthèses dans un appel de fonction de base
Pour un appel de fonction de style C, par exemple
plus(a, b); // Parentheses surrounding only the arguments, comma separated
Alors le code Haskell équivalent sera
(plus a b) -- Parentheses surrounding the function and the arguments, no commas
Dans Haskell, les parenthèses ne sont pas explicitement requises pour l'application de fonction et ne sont utilisées que pour désambiguïser des expressions, comme en mathématiques; ainsi, dans les cas où les crochets entourent tout le texte de l'expression, les parenthèses ne sont en fait pas nécessaires et les suivantes sont également équivalentes:
plus a b -- no parentheses are needed here!
Il est important de se rappeler que dans les langages de style C, la fonction
Parenthèses dans les appels de fonctions incorporés
Dans l'exemple précédent, nous n'avons pas eu besoin des parenthèses, car elles n'affectaient pas le sens de l'instruction. Cependant, ils sont souvent nécessaires dans une expression plus complexe, comme celle ci-dessous.
En C:
plus(a, take(b, c));
En Haskell, cela devient:
(plus a (take b c))
-- or equivalently, omitting the outermost parentheses
plus a (take b c)
Notez que ce n'est pas équivalent à:
plus a take b c -- Not what we want!
On pourrait penser que le compilateur sachant que take
est une fonction, il pourrait savoir que vous voulez l'appliquer aux arguments b
et c
et transmettre son résultat à plus
.
Cependant, dans Haskell, les fonctions prennent souvent d'autres fonctions comme arguments et peu de distinction est faite entre les fonctions et les autres valeurs. et donc le compilateur ne peut pas assumer votre intention simplement parce que take
est une fonction.
Et ainsi, le dernier exemple est analogue à l'appel de fonction C suivant:
plus(a, take, b, c); // Not what we want!
Application partielle - Partie 1
Dans Haskell, les fonctions peuvent être partiellement appliquées; Nous pouvons considérer toutes les fonctions comme prenant un seul argument et renvoyer une fonction modifiée pour laquelle cet argument est constant. Pour illustrer cela, nous pouvons encadrer les fonctions comme suit:
(((plus) 1) 2)
Ici, la fonction (plus)
est appliquée à 1
donnant la fonction ((plus) 1)
, qui est appliquée à 2
, donnant la fonction (((plus) 1) 2)
. Parce que plus 1 2
est une fonction qui ne prend aucun argument, vous pouvez la considérer comme une valeur simple; Cependant, dans Haskell, il y a peu de distinction entre les fonctions et les valeurs.
Pour aller plus en détail, la fonction plus
est une fonction qui ajoute ses arguments.
La fonction plus 1
est une fonction qui ajoute 1
à son argument.
La fonction plus 1 2
est une fonction qui ajoute 1
à 2
, qui est toujours la valeur 3
.
Application partielle - Partie 2
Comme autre exemple, nous avons la fonction map
, qui prend une fonction et une liste de valeurs, et applique la fonction à chaque valeur de la liste:
map :: (a -> b) -> [a] -> [b]
Disons que nous voulons incrémenter chaque valeur dans une liste. Vous pouvez décider de définir votre propre fonction, ce qui en ajoute une à son argument, et map
cette fonction sur votre liste.
addOne x = plus 1 x
map addOne [1,2,3]
mais si vous avez un autre regard sur la définition de addOne
, avec des parenthèses pour les mettre en évidence:
(addOne) x = ((plus) 1) x
La fonction addOne
, appliquée à toute valeur x
, est identique à la fonction partiellement appliquée plus 1
appliquée à x
. Cela signifie que les fonctions addOne
et plus 1
sont identiques, et nous pouvons éviter de définir une nouvelle fonction en remplaçant simplement addOne
par plus 1
, sans oublier d'utiliser des parenthèses pour isoler plus 1
tant que sous-expression:
map (plus 1) [1,2,3]