J'ai lu sur Haskell et j'ai du mal à comprendre comment les définitions de la fonction sont traitées dans cette langue.
Disons que je définissais un si je demande HASKELL pour son type P> i get p> somme code> Fonction: p>
=> code>? At-il quelque chose à voir avec les expressions de Lambda? C'est comme ça que l'on signale que ce qui suit l'opérateur
=> code> est un, en C #. Li>
a -> a -> a code> signifie? Par inspection des yeux sur plusieurs fonctions que j'ai essayé, il semble que les arguments
a -> a code> sont les arguments et la finale
-> A code> est le résultat de la fonction de somme. Si cela a raison, pourquoi pas quelque chose de
(a, a) -> A code>, qui semble plus intuitif? Li>
ol> p>
5 Réponses :
C'est a -> A -> A code> plutôt que
(a, a) -> A, un code> à cause de Currying . Faire de plaisir: Currying était (re) inventé par Haskell Curry! Fondamentalement, cela signifie que si vous fournissez un argument unique, vous récupérerez une autre fonction de type
a -> A code>, une application partielle de la somme. P>
Même après avoir lu l'intro de l'article de Wikipedia, je ne peux pas obtenir quel est le point de currying :(
Je n'ai pas le point non plus! C'est juste une de ces choses que vous faites i> dans la programmation fonctionnelle ...
Vous curry fonctionne afin que vous puissiez les appliquer partiellement. Voulez-vous ajouter 3 à chaque élément d'une liste? Aucun problème! - Carte (+3) [1, 2, 3, 4, 5]
@Paul Harvey: En fait, carte (+3) code> est un mauvais exemple d'application partielle, c'est vraiment un. Section de l'opérateur.
mappe ((+) 3) code> est une application partielle.
Si vous avez la fonction "SendMessage pour taper le contenu" et que vous envoyez souvent des messages d'état numériques sur "Server", vous pouvez créer une fonction d'assistance avec application partielle: "SendStatus = SendMessage Server Number" et l'utiliser comme "SendStatus 10".
@Matajon: à Haskell L'application partielle d'un opérateur d'infixe est appelée section, oui. C'est une demande toujours partielle cependant.
Une autre façon d'y penser: que signifie "plus 1"? Une fonction entièrement conforme à celle-ci qui lie l'une des entrées à 1. La capacité de générer de nouvelles fonctions existantes, même des familles entières de nouvelles fonctions, à travers des opérations élémentaires telles que des applications partielles, est le point.
Le En d'autres termes: vous appelez d'abord si vous voulez Cependant, le "style de curry" (fonctions renvoyant des fonctions pour simuler plusieurs paramètres) est beaucoup plus souvent utilisé que le style de tuple, car il vous permet d'appliquer facilement partiellement des fonctions. Exemple num a => code> signifie "dans ce qui suit,
A code> doit se référer à un type d'une instance de type tyclass
num code>" ( qui est un peu comme une interface pour les types de nombres). P>
=> code> L'opérateur sépare les "contraintes de clastographie" du "corps" du type. C'est un peu comme le
où code> opérateur pour des contraintes génériques dans C #. Vous pouvez le lire comme une implication logique comme "si
a code> est un type numérique, alors
somme code> peut être utilisé avec type
a -> a -> A -> a code > ". P>
a -> a -> a code> signifie "une fonction qui prend un
a code> et renvoie une fonction qui prend un
a code> et renvoie un
a code> ". Pour ce faire, vous devez comprendre que
somme x y code> analyse comme
(somme x) y code>. P>
somme code> avec l'argument
x code>. Vous récupérez ensuite une nouvelle fonction de type
a -> A code>. Vous appelez ensuite cette fonction avec l'argument
y code> et vous récupérez maintenant une fonction de type
A code>, où
a code> est le type de
x code> et
y code> et doit être une instance du type code> Typeclass. p>
somme code> pour avoir type
num a => (a, a) -> a code>, vous pouvez le définir comme
somme (x, y ) = x + y code>. Dans ce cas, vous avez une fonction qui prend un tuple contenant deux
A code> s et renvoie un
a code> (où
a code> est à nouveau une instance de < code> num code> tyteclass). p>
carte (somme 5) [1,2,3] code>. Si vous aviez défini
somme code> avec un tuple, vous devez faire
carte (\ y -> somme 5 y) [1,2,3] code>. P >
Ceci est parce que
Si une fonction doit prendre plusieurs valeurs, la fonction aurait été une fonction au curry ou qu'il doit prendre un single tuple em>. P> Si nous ajoutons des parenthèses, la signature de fonction devient : p> in haskell, la signature de fonction: par conséquent, la définition de la fonction En effet, cela conduit à la fonction de curry / partielle. P> Le concept de Currying est essentiel dans des langages fonctionnels comme Haskell, car vous voudrez faire des choses comme: p> dans ce code (somme 5 ) est une fonction qui prend un seul paramètre, cette fonction (somme 5) sera appelée à chaque élément de la liste, par exemple ((somme 5) 1) renvoie 6. p> si maintenant , la deuxième question, qu'est-ce que a -> b code> signifie une fonction "Domaine" de la fonction est
a < / code> et la "codomaine" de la fonction est
b code>; Ou dans la langue d'un programmeur, la fonction prend un paramètre de type
A code> et renvoie une valeur de type
B code>. p>
Somme :: Num -> (Num -> Num) Code> MOYEN est "Une fonction qui prend un paramètre de type
a code> et renvoie une fonction de type
num -> num Code> ". P>
Somme code> avait une signature de
somme :: (num, num) -> num code>, puis La somme devrait recevoir tous les deux paramètres en même temps car la somme est une "fonction qui reçoit un
tuple (num, num) code> et renvoie un numéro". p>
num a => a -> a code> signifie? C'est fondamentalement un raccourci pour dire que chaque fois que vous voyez
a code> dans la signature, remplacez-le par num ou avec l'une de sa classe dérivée. P> p>
Vous abusez un peu la notation: num code> est une typlass, pas un type.
La documentation Haskell n'est pas trop claire à ce sujet, mais (num a) => signifie que la fonction fonctionne pour tous les cas où a est un numéro ou en dérive (donc est un nombre). P>
Voir aussi: http: //www.cse.unsw .edu.au / ~ EN1000 / HASKELLL / INBUILT.HTML P>
0. strong> Le haskell également, ne nommez pas la fonction 1. Strong> de toute façon, le ici, le Une classe de type est similaire à celle de C #, ou plus spécifiquement, un CONTRAINT DE TYPE DE BASE D'INTERFACE EN GENRES . Voir la question Expliquer les classes de type à Haskell em> pour plus d'informations . P> 2. strong> => code> n'a rien à voir avec C # 'S
=> code>. In Haskell une fonction anonyme est créée avec
somme code> car Une telle fonction existe déjà en prélude. Appelons-le
plus code> à partir de maintenant pour éviter la confusion. P>
=> code> in haskell fournit un contexte au type. Par exemple: p>
Afficher a => code> signifie
A code> type doit être une instance de Classe de type em>
Afficher code>, ce qui signifie
A code> doit être convertible à une chaîne. De même,
(num a) => A -> A -> A code> signifie que le type
A code> doit être une instance du numéro de classe de type, ce qui signifie
a doit être comme un numéro. Cela met une contrainte sur
A code> de sorte que
montrez code> ou
plus code> n'acceptera pas une entrée non prise en charge, par ex.
plus "56" "ABC" code>. (La chaîne n'est pas comme un nombre.) P>
a -> a -> a code> signifie
a -> (a -> a) code>. Par conséquent, il s'agit en fait d'une fonction unaire qui renvoie une autre fonction. P>
plusFourToList = \l -> map(\y -> plus(4,y), l)
Une bonne réponse, sauf que je crains toujours lorsque j'entends quelqu'un dire que les classes de types sont comme des classes d'interface. Ils ont un rôle quelque peu analogue, mais le raisonnement de cette analogie vous évitera sérieusement. En particulier dans HASKELL, une classe de type n'est pas elle-même un type, vous ne pouvez donc pas écrire "[NUM]" pour signifier une liste de chiffres.
Bien que l'écriture (num a) => [A] n'est pas vraiment si différente. Je crois, tant que vous précisez que l'analogie de l'interface est simplement une simple pour vous aider à démarrer, c'est bon.
Même si c # avait une interface num code>, quelque chose comme
list
(num a) => [a] code>, Parce que
[5 :: int, 3.5 :: double] code> n'est pas une valeur valide de type
(num a) => [a] code> in haskell. Je pense que cela surprend beaucoup de gens quand ils voient d'abord des classes de type.
Si vous voulez comprendre HASKELL, vous feriez mieux d'obtenir une (bonne) introduction au lieu de demander à chaque partie de la langue. Stackoverflow.com/Questtions/1012573/how-to- Learn-Haskell / ... liens vers quelques bonnes ressources et dispose de nouveaux conseils.