Question

Je joue donc avec le combinateur y et les fonctions anonymes, et je suis tombé sur cette erreur étrange:

Couldn't match expected type `t0 -> t1 -> t2'
            with actual type `forall b. b -> [b] -> [b]'
The lambda expression `\ (n :: Int) newVal xs -> ...'
has three arguments,
but its type `Int -> forall b. b -> [b] -> [b]' has only one

( code source qui crée l'erreur , et version que j'ai finalement mise en service )

Si je modifie légèrement les types pour éviter le polymorphisme de rang N (utilisez forall b. Int -> b -> [b] -> [b]) , l'erreur estsimilaire:

Couldn't match expected type `t0 -> t1 -> t2 -> t3'
            with actual type `forall b. Int -> b -> [b] -> [b]'
The lambda expression `\ (n :: Int) newVal xs -> ...'
has three arguments,
but its type `forall b. Int -> b -> [b] -> [b]' has none

Quelqu'un pourrait-il m'expliquer pourquoi forall b. b -> [b] -> [b] n'a pas d'arguments?

Était-ce utile?

La solution

Puisque vous utilisez GHC 7, cela semble avoir la même cause fondamentale que le bogue signalé dans http://hackage.haskell.org/trac/ghc/ticket/4347 .Bien que ce rapport de bogue parle de polymorphisme imprédicatif, il semble que ce soit probablement dans un problème d'unification dans le polymorphisme de rang supérieur.Dans votre cas, il est déclenché par votre placement du forall, ce qui rend le type syntaxiquement rang-2.

Notez que ce n'est pas vraiment un bug.La clarification supplémentaire fournie montre clairement qu'il s'agit d'un comportement prévu, en ce que les instanciations polymorphes de types, y compris les types de rang N et les types imprédicatifs, ne sont pas déduites.L'ajout soigneux de signatures de type peut le faire fonctionner.

Mais comme le type n'était pas du tout destiné à être de rang supérieur, dans votre cas, il est préférable de s'en débarrasser.

Autres conseils

Voulez-vous plutôt

forall b. Int -> b -> [b] -> [b]

ou vraiment

Int -> forall b . b -> [b] -> [b]

Je suppose que vous avez écrit les mauvais types.

La suppression des annotations de type aide quelque peu, ce qui conduit à des erreurs moins déroutantes:

A.hs:7:76:
    Occurs check: cannot construct the infinite type: a0 = [a0]
    In the third argument of `replaceNth', namely `arg'
    In the expression: replaceNth m (replaceNth n v (arg !! m)) arg

oui

 \m n v arg -> replaceNth m (replaceNth n v (arg !! m)) arg

a déjà des problèmes.


Types de rang N et variables de type à portée lexicale

En utilisant un forall pas dans une position la plus extérieure, vous êtes tombé sur rang N types . Le forall sur votre b interne indique qu'il doit être opaque, polymorphe et sans rapport avec vos autres utilisations du type b. Ce n'est probablement pas ce que vous aviez l'intention de faire.

Ceci est subtilement distinct des variables de type à portée lexicale , qui peuvent également être introduites par un forall à la position la plus externe , comme décrit ici .

En supprimant (je pense) les codes génériques erronés dans la position non la plus externe, vous obtiendrez des erreurs de type beaucoup plus simples.

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