Je suis assez nouveau à Haskell et pas trop à l'aise avec son système de type. Et je me demande s'il est possible de définir le type (DataType?), Les instances peuvent être appelées comme des fonctions?
analogues sont p> méthode en python ou en classe Méthode p> en C ++. (Plus d'exemples sont donnés dans Wikipedia pour le mot "objet de fonction"). P> L'exemple d'application d'une telle construction est polynom. L'objet est défini par la liste de ses coefficients, c'est-à-dire que je voudrais avoir de type comme celui-ci: p> maintenant, je peux définir la fonction p> (Ici, je ne me dérange pas, pour pouvoir appeler Polynom avec des coefficients d'into sur des flotteurs ... il est juste des détails techniques) p> maintenant je peux l'appeler sur mon polinomial ( Invite interactive): p> mais de cette façon n'est pas trop fantaisie. Est souhaitable d'être capable d'appeler polynôme directement comme p> de sorte que la question est la suivante: il est possible de définir un tel type polynomial, que des objets (instances) peuvent être appelés (d'occasion). comme des fonctions)? Peut-être que ce modèle peut être mis en œuvre d'une autre manière, sans impliquer les "données"? Peut-être que certains jouent avec des types de fonctions ou de la SMTH. sinon? P> Bien sûr, cette idée peut être appliquée non seulement aux polynômes. En fait, à n'importe quelle fonction, qui doit "avoir du type" et a "certaines données jointes" (en cas de polynôme - il est coefficients). P> ou si cela n'est pas possible, il y a une raison spécifique. Pour cela ou ce n'est tout simplement pas pris en charge? P> PS: Il me semble que cette approche directe (comme décrit ci-dessus) est impossible, car être appelable mypoly doit être de type (INT -> INT). Mais tapez (int -> int) ne peut avoir aucune donnée jointe (i.g. coefficients polynomiaux). Mais je veux m'assurer que j'ai raison. P> p>
3 Réponses :
Je peux me procurer ma terminologie ici, car je ne suis pas un vétéran Haskell moi-même. Cependant, de ma compréhension de Haskell:
Comme HASKELL n'est pas orientée objet, il n'a pas d'objet ni d'instances (au sens traditionnel, c'est-à-dire). Au lieu d'instances d'un type de données, vous avez des valeurs du type de données. Cela étant dit, car les fonctions sont des données (valeurs) comme des entiers et des chaînes, vous pouvez avoir des valeurs appelables en ce sens qu'ils peuvent porter leur propre contexte (comme une instance dans OO World). P>
Si votre objectif est d'avoir une valeur que vous transmettez, cela porte le MAINTENANT, le type de CallMypoly est le suivant: p> et vous pouvez l'appeler comme ceci: p> équivalent à: p> polynom A code>, vous pouvez simplement évaluer partiellement em> votre fonction callpoly code>, puis pensez de cela comme votre "polynome appelable". Exemple: p>
Le type de CallMypoly code> n'est que polymorphe si le monomorphisme ne s'applique pas. Si vous définissez CallMypoly code> comme indiqué, le MR s'applique (s'il n'est pas désactivé par -xnomonomorphistressrections ou pragmes). Pour obtenir le type polymorphique, 1) Donner une signature de type 2) Bind avec un argument, CallMypoly X = CallPoly MyPoly X Code> ou 3) Désactiver M.
Oui, dans HASKELL, vous ne pouvez pas avoir d'objets appelables car cela gâcherait beaucoup l'inférence de type. Vous devrez donner des noms explicites à vos fonctions, comme dans les langues oo qui ne prennent pas en charge D'autre part, une application partielle de la fonction et des fermetures le font. Très facile à obtenir une fonction polynomiale d'une représentation polynomiale de sorte que la limitation n'est pas si mauvaise. p> __ appel __ code> et nécessitent des noms de méthodes explicites.
C'est bien que vous soyez familiarisé avec le concept de "objet de la fonction" C ++, car c'est une bonne introduction à l'idée de Haskell de ce que vous pouvez faire avec des fonctions anciennes ... précisément, curry, application partielle et travaux de passage comme des arguments à d'autres fonctions.
en C ++, votre code ressemblerait à quelque chose comme: p> Ceci est fondamentalement exprimant une seule fonction pure: un évaluateur polynomial qui prend une liste de coefficients et une valeur. Cela pourrait tout aussi facilement être exprimé en C ++ comme suit: p> mais ce formulaire n'est pas curry em> comme le formulaire précédent est. La bonne chose à propos de la forme au curry est que vous pouvez dire: p> au lieu de: p> ok. Nous pensons donc à cet "objet de fonction" en tant que concept de programmation orienté objet - un objet qui masqueurs en tant que fonction - mais oublions les objets maintenant. Si vous le regardez à Haskell, il s'agit simplement d'une fonction et ne nécessite aucun type de données défini par l'utilisateur pour exprimer joliment: p> Vous pouvez l'appeler "normalement" (comme avec mais parce que les fonctions HASKELL sont curreuses, vous pouvez appliquer partiellement (comme Avec le évaluatepolynomial () code> ci-dessus), appliquez-le sur les deux arguments à la fois: p> Objet de fonction Polynôme Code>): P> do
let (P p) = mkPolynomial [1, 2, 3]
print (p 4)
print (p 5)
print (p 6)
Merci pour ce tutoriel. L'idée est belle. Mais je pense toujours au style oo. Avec votre solution, je ne comprends pas, comment définir d'autres opérations (ajouter, différencier, etc.) et celles-ci devraient être polymorphes. Par exemple. Je peux soit avoir des splines, soit appelables, soit une addition, une différenciation, etc. Je ne peux pas comprendre, comment adopter votre solution à ce cas. Le problème est que dans P, nous avons perdu des informations sur les coefficients (qui, dans ma compréhension, devraient être encapsulées en objet polynomial).
Eh bien, si vous voulez, vous pouvez définir nouveautype polynomial a = num a => p {coefficients :: [a]} code> et Evaluatpolynomial :: num A => Polynôme a -> A - > A code>. Ceci est essentiellement la même chose que votre définition initiale. Mais c'est aussi la même chose que la mienne, avec juste un peu de sucre supplémentaire de type. Vous pouvez toujours dire laisser p = évaluatepolynomial (p [1, 2, 3]) code> ou autre.
Cela a toujours le même problème (que j'essaie de résoudre dans ces questions): la valeur, qui a des informations sur les coefficients et la valeur, qui est la fonction est distincte (elles sont liées à différentes variables). Mais je veux que ceux-ci soient les mêmes. Dans ce cas, il est plus agréable (IMHO) de définir de classe appelable a ... code> avec une opération infixe comme (|||) :: (A int) -> int -> int code> et mettre en œuvre cette opération pour le polynôme. Puis appelez-le comme let y = mypoly ||| x code> (cette solution a été proposée dans d'autres réponses). Quoi qu'il en soit, merci pour vos commentaires.
La classe appelable code> que vous proposez existe déjà comme catégorie code> . Il existe également un type de données pratique qui existe quels modèles catégorie code> joliment: (->) code>. Votre infixe (|||) code> est identique à celle de mon fonction polynomial code> ci-dessus. C'est-à-dire que j'aurais pu l'appeler (|||) code> et a donc été capable d'écrire [1, 2, 3] ||| 4 code>. Point est que les solutions sont identiques; J'essaie de vous aider à vous éloigner de la pensée de OO qui complique uniquement le problème.
Qu'est-ce qui ne va pas avec
let mypoly = callpoly (polynôme [1, 2, 3]) code>?Pourquoi ne pas simplement inventer votre propre application polynomiale 'Sytax', par ex.
[] ||| x = 0; (C: CS) ||| x = c + x * (CS ||| x) code> dansGHCI code> Vous demandez[1,2,3,4,5] ||| 3 code> et obtenir547 code> comme réponse.Voir: Stackoverflow.com/Questtions/6482970/...
@shang merci. Le dernier lien est exactement ce que je cherchais. Désolé, je ne l'ai pas trouvé moi-même.