Error extraño cuando se usa variables de tipo alcance y el combinador y en Haskell
-
28-10-2019 - |
Pregunta
Así que estoy jugando con las funciones de Y-Combinator y Anonymous, y me encontré con este extraño error:
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
(código fuente que crea el error, y versión que finalmente tuve funcionando)
Si yo Modifique los tipos ligeramente para evitar el polimorfismo de rango (usar forall b. Int -> b -> [b] -> [b]
), el error es similar:
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
¿Alguien podría explicarme por qué forall b. b -> [b] -> [b]
¿No tiene argumentos?
Solución
Como está utilizando GHC 7, esto parece tener la misma causa raíz que el error informado en http://hackage.haskell.org/trac/ghc/ticket/4347 . Si bien ese informe de error habla sobre el polimorfismo impredicativo, parece que es muy probable que sea en un problema de unificación en el polimorfismo de mayor rango. En su caso, se está activando por su colocación del forall
, que hace que el tipo sintácticamente rango-2.
Tenga en cuenta que esto no es realmente un error. La aclaración adicional proporcionada deja en claro que esto es un comportamiento previsto, ya que no se infiren instanciaciones polimórficas de los tipos, incluidos los tipos de rango y los tipos impredicativos. La adición cuidadosa de las firmas de tipo puede hacer que funcione.
Pero dado que el tipo no tenía la intención de ser un rango más alto, en su caso, en su caso, es mejor deshacerse de eso.
Otros consejos
Prefieres que quieras
forall b. Int -> b -> [b] -> [b]
O realmente
Int -> forall b . b -> [b] -> [b]
Leería este último: una función que toma un int y devuelve Algo opaco que probablemente no sea lo que crees que es.
Supongo que había escrito los tipos incorrectos.
Eliminar las anotaciones de tipo ayuda de alguna manera, lo que lleva a errores menos confusos:
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
asi que
\m n v arg -> replaceNth m (replaceNth n v (arg !! m)) arg
ya tiene problemas.
Rango de n tipos y variables de tipo de alcance léxico
Usando un forall
no en una posición más externa, ha tropezado con rango norte tipos. los forall
en tu interior b
dice que debe ser opaco, polimórfico y no relacionado con sus otros usos del b
escribe. Es probable que esto no sea lo que pretendía hacer.
Esto es sutilmente distinto de Variables de tipo de alcance léxico, que también puede ser introducido por un valiente en el más exterior posición, como descrito aquí.
Eliminando el (creo) equivocado forall
S En la posición no más alta, obtendrá errores de tipo mucho más simples.