Question

J'ai écrit le code suivant dans Haskell pour calculer le produit scalaire de deux vecteurs, mais ne peut pas le compiler en raison de l'erreur suivante:

cannot construct infinite type: a = [a] When generalising the type(s) for dot'

dot :: (Num a) => [a] -> [a] -> a

[] `dot` [] = 0
x@[xi,xs] `dot` y@[yi,ys] = xi*yi + (xs `dot` ys)

J'ai examiné cette question à l'avance à titre indicatif. Pour autant que je peux dire, les types sont corrects. x, y et les deux [] 's sont des listes, et la fonction renvoie un nombre.

Qu'est-ce qui ne va pas?

Était-ce utile?

La solution

Vous confondez la syntaxe pour une liste de deux éléments [x, y] avec la syntaxe pour diviser une liste dans le premier élément et le reste de la liste (x:y). Essayez ceci:

dot :: (Num a) => [a] -> [a] -> a

[] `dot` [] = 0
x@(xi:xs) `dot` y@(yi:ys) = xi*yi + (xs `dot` ys)

Les motifs de @ sont également inutiles, d'ailleurs.

Autres conseils

réponse Ganesh est sur place. Permettez-moi de préciser brièvement sur la signification d'un « type infini ».

dot a cette définition de type:

dot :: (Num a) => [a] -> [a] -> a

Cela signifie que dot prend deux listes d'éléments de Num et renvoie un Num. Votre définition inclut cette ligne:

x@[xi,xs] `dot` y@[yi,ys] = xi*yi + (xs `dot` ys)

Depuis, comme Ganesh souligne, [xi,xs] est une liste composée de deux éléments, xi et xs devraient être Nums. Idem pour yi et ys. Mais ils sont passés comme arguments à dot:

xs `dot` ys

Cela signifie que xs et ys doivent être des listes de Nums. Cela conduit à une contradiction.


Une autre façon de regarder cela, est à un moment oublier la définition du type de dot. Cette ligne,

x@[xi,xs] `dot` y@[yi,ys] = xi*yi + (xs `dot` ys)

indique que dot prend deux listes dont les éléments sont les paramètres appropriés pour dot. Mais la seule façon pour que de donner un sens, est si ces listes sont infiniment imbriqués . Ce n'est pas autorisé, ni raisonnable.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top