Question

Je suis en train de compiler la fonction suivante dans Haskell pour imiter la différenciation d'un polynôme dont les constantes sont spécifiées dans une liste numérique:

diff :: (Num a) => [a] -> [a]
diff [] = error "Polynomial unspecified"
diff coeff = zipWith (*) (tail coeff) [0..]

Haskell refuse de le compiler, me donner la raison suivante:

Could not deduce (Enum a) from the context (Num a)
 arising from the arithmetic sequence `0 .. ' at fp1.hs:7:38-42
Possible fix:
 add (Enum a) to the context of the type signature for `diff'
In the third argument of `zipWith', namely `[0 .. ]'
In the expression: zipWith (*) (tail coeff) ([0 .. ])
In the definition of `diff':
diff coeff = zipWith (*) (tail coeff) ([0 .. ])

Pourquoi Haskell traite la liste [0..] comme un type Enum, et comment puis-je résoudre ce problème. Gardez à l'esprit que je veux profiter de l'évaluation paresseuse ici, d'où la liste infinie.

Était-ce utile?

La solution

[0..] est le sucre syntaxique pour enumFrom 0, défini dans la classe Enum. Parce que vous voulez générer une liste de as avec [0..] le compilateur exige a être en classe Enum.

Vous pouvez ajouter le Enum a à la signature de type de la fonction ou le travail autour d'elle en générant un [0..] :: [Integer] et utiliser pour obtenir un fromInteger de cette Num (qui est défini dans la classe [a]):

diff :: (Num a) => [a] -> [a]
diff [] = error "Polynomial unspecified"
diff coeff = zipWith (*) (tail coeff) (map fromInteger [0..])

Autres conseils

Le type correct de diff doit être

diff :: (Num a, Enum a) => [a] -> [a]

parce que l'utilisation de [x..] exige le type d'instancier Enum.

[0..] est un raccourci pour enumFrom 0 Voir

Voici un résumé rapide de ce que voit le compilateur quand il regarde cette fonction:

  • [0 ..] est une liste de choses qui ont les deux cas Num et Enum. Il doit être Num à cause du « 0 », et il doit être un Enum en raison de la « .. »
  • Je me demande d'appliquer (*) aux éléments de coeff et [0 ..] un par un. Étant donné que les deux arguments (*) doivent être du même type et [0 ..] a une instance pour Enum, coeff doit également avoir une instance pour Enum.
  • Erreur! La signature de type de diff mentionne seulement que coeff a une instance pour Num, mais je l'ai déjà déterminé qu'il doit au moins avoir une instance pour Enum aussi.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top