Haskell : comprendre “Aucune instance pour” messages d'erreur dans ghci
Question 1
Salut, si dans WinGHCi j'ai volontairement effectuer les opérations suivantes mauvais morceau de code :
3 4
Puis le message d'erreur que j'obtiens est
<interactive>:1:1:
No instance for (Num (a0 -> t0))
arising from the literal `3'
Possible fix: add an instance declaration for (Num (a0 -> t0))
In the expression: 3
In the expression: 3 4
In an equation for `it': it = 3 4
Quoi exactement No instance for (Num (a0 -> t0))
veux dire?
Question 2
Pourquoi le morceau de code suivant :
(+) 2 3 4
<interactive>:1:7:
No instance for (Num (a0 -> t0))
arising from the literal `3'
Possible fix: add an instance declaration for (Num (a0 -> t0))
In the second argument of `(+)', namely `3'
In the expression: (+) 2 3 4
In an equation for `it': it = (+) 2 3 4
rendement est légèrement différent de l'erreur à partir de la deuxième partie du code :
2+3 4
<interactive>:1:3:
No instance for (Num (a1 -> a0))
arising from the literal `3'
Possible fix: add an instance declaration for (Num (a1 -> a0))
In the expression: 3
In the second argument of `(+)', namely `3 4'
In the expression: 2 + 3 4
À savoir dans le premier morceau de code que nous avons No instance for (Num (a0 -> t0))
où, comme dans le deuxième morceau de code que nous avons No instance for (Num (a1 -> a0))
.
[Réponse à ehird]
(Questions déplacé de répondre à des commentaires) :
1) j'apprécie les deux dernières expressions sont différentes, mais dites-vous que je ne devrais pas essayer de comprendre pourquoi l'interprète choisit (Num (a0 -> t0))
pour l'ancien et (Num(a1 -> a0))
pour ce dernier, outre le fait qu'ils sont différents?
2)Salut, et avec l'ancien quand vous dites "Mais il n'y a pas de Num exemple pour les fonctions" que voulez-vous dire? Désolé, je ne suis pas clair sur ce que le concept d'une instance est. En outre, juste par curiosité, pourriez-vous utiliser votre instance Num (a -> b)
méthode de quelque sorte de dire à l'interprète 3 4
comme 4 modulo 3
?
OriginalL'auteur artella | 2012-04-29
Vous devez vous connecter pour publier un commentaire.
Mon intention est de compléter ehird de répondre avec un peu plus d'explication. Quand vous avez écrit l'expression
Puis le Haskell interprète pense que vous essayez d'appliquer la fonction
3
à ce que4
est. Pour Haskell pour interpréter3
comme une fonction, il a besoin de faire un appel à la fonctionafin d'obtenir une fonction (c'est à dire quelque chose du type
a -> b
) de l'entier3
. Maintenant,fromInteger
est définie dans leNum
typeclass d'avoir la signaturec'est à dire lorsque vous effectuez ce type de
x
une instance de laNum
classe, vous donnez une mise en œuvre defromInteger
qui raconte Haskell comment faire pour convertir un entier littéral dans unx
. Dans votre cas,x
est le type de fonction dea -> b
. Donc allons-y!D'abord, réutilisable. Pour faire
x
une instance deNum
Haskell exige que nous aussi en faire une instance deShow
etEq
:Maintenant, nous allons dire que nous voulons interpréter
3 4
"4 modulo 3". Ensuite, nous devons dire Haskell comment interpréter tout entier comme une fonction qui s'appellemod
. En outre, depuismod
accepte uniquement les types intégraux (il a la signaturemod :: Integral a => a -> a -> a
) ensuite, nous devons nous restreindre les types dea
etb
à faire partie intégrante:À créer une instance de
Num
nous avons besoin de donner des implémentations de(+)
,(-)
,(*)
etfromIntegral
(en fait, on doit définir un couple d'autres fonctions, mais nous allons vous inquiétez pas à ce sujet).Il y a une assez moyen naturel de définir l'addition, la soustraction et de multiplication (de tous les codes à partir d'ici, fait partie de la
Num
instance et doit être mis en retrait par rapport à l'instance de la déclaration)c'est à dire lorsque vous ajoutez deux fonctions
f
etg
, vous obtenez une nouvelle fonction qui s'applique à la foisf
etg
à son argument, et ajoute ensuite de l'ensemble. Depuis nous avons exigé que le résultat de l'applicationf
etg
est de type intégral, nous savons qu'il est judicieux d'ajouter jusqu'à leurs sorties.Pour interpréter un entier comme une fonction, nous pouvons écrire
c'est à dire quand on a un entier
n
, nous sommes de retour d'une fonction d'un paramètrem
qui, lorsqu'on l'appelle, s'assure que les deux arguments sont de même type (en appelantfromIntegral
sur deux d'entre eux) et les utilise comme arguments de la fonctionmod
.Enfin, un peu plus passe-partout pour arrêter Haskell se plaindre:
Nous pouvons tester cela. J'ai mon code dans un fichier appelé numfun.hs. Je démarre le Haskell interprète et charger mon fichier:
Maintenant, je peux définir quelques fonctions:
Je peux ajouter ou de soustraire:
Et je peux appeler des numéros de fonctions:
OriginalL'auteur Chris Taylor
La première erreur se produit à cause d'un entier littéral comme
4
peut être de tout type avec unNum
instance. C'est,4
a le type(Num a) => a
, de sorte qu'il peut servir deInteger
, unDouble
, unRational
, etc. Depuis3
à un argument (4
), il sait que, dans le contexte,3
doit être un type de fonction (c'est à direa0 -> t0
pour certainsa0
ett0
). Mais il n'y a pasNum
exemple pour les fonctions, de sorte que votre utilisation de3
comme une fonction n'est pas valide. Si vous avez ajouté uninstance Num (a -> b)
, cela pourrait fonctionner, mais vous ne voulez probablement pas à.Comme pour ces derniers, les deux messages d'erreur sont équivalentes; les noms générés par GHC ont pas de signification particulière. Les lettres sont généralement dérivée à partir des variables de type dans les types de fonctions que vous utilisez, et les numéros sont ajoutés à garder les choses sans ambiguïté. Dans ce cas, la deuxième expression est équivalente à
(+) 2 (3 4)
(parce que la fonction de demande se lie plus serré que tout opérateur infixe), ce qui n'est pas tout à fait le même que celui de votre premier morceau de code.(Num (a0 -> t0))
pour l'ancien et(Num(a1 -> a0))
pour ce dernier, outre le fait qu'ils sont différents? Merci.Salut, et avec l'ancien quand vous dites "Mais il n'y a pas de Num exemple pour les fonctions" que voulez-vous dire? Désolé, je ne suis pas clair sur ce que le concept d'une instance est. En outre, juste par curiosité, pourriez-vous utiliser votre
instance Num (a -> b)
méthode de quelque sorte de dire à l'interprète3 4
comme '4 modulo 3'? MerciOriginalL'auteur ehird