sintaxis opciones multiplicar instancias hacer definir datos data contador como basica haskell compiler-errors

opciones - Error Haskell: "No hay instancia para(Enum[Int])



or en haskell (2)

Tengo el siguiente código:

betaRest :: Int -> [Int] -> Int betaRest n prevDigits | n == 0 = (length prevDigits) | otherwise = (sum (map (betaRest (n - 1)) [0..9])) betaFirst :: Int -> Int betaFirst n | n == 0 = 0 | otherwise = (betaRest (n - 1) [1..9])

Me da los siguientes errores y no sé por qué.

1) No hay instancia para (Enum [Int]) que surja de la secuencia aritmética ''0 .. 9''

2) No hay instancia para (Num [Int]) que surja del literal ''0''

¿Haskell piensa que las cosas hechas con el operador ".." son enumeraciones? Pero ¿por qué no hay un error para la línea que está 4 líneas abajo (con "[1..9]") entonces?

Editar: Lo que quiero que el código haga es así (proceduralmente):

int betaRest(int n, int[] prevDigits) { if (n == 0) return prevDigits.length; else { sum = 0; foreach prevDigit in prevDigits { sum += betaRest(n - 1, [0..9]); } return sum; } } int betaFirst(int n) { if (n == 0) return 0; else return betaRest(n - 1, [1..9]); }

Por lo tanto, betaPrimer (1) == 9 y betaPrimer (2) == 90. Sí, alguien puede querer sugerir una fórmula para generar esto, pero voy a agregar un filtro de algún tipo a [0..9 ], reduciendo así el rango.


betaRest para map . El mapa es (a -> a) -> [a] -> [a] así que para la lista [Int] que lo pasa quiere una función Int -> Int . Pero betaRest aplicado parcialmente es [Int] -> Int .

En cuanto a [0..9] su tipo es (Enum t, Num t) => [t] y se traduce en la aplicación enumFromTo 0 9 . Así que el compilador calculó su error al revés: si define instancias Num y Enum especiales para listas, entonces [0..9] convierte en una lista de listas de int, entonces su aplicación tendrá sentido.

Pero creo que quieres usar la función inits o tails . Háganos saber lo que quiere lograr para que podamos ayudar con la solución.

Una solución mínima sería agregar prevDigits como argumento para map y usar una abstracción lambda para ignorar prevDigit no prevDigit :

| otherwise = sum (map (/prevDigit -> betaRest (n - 1) [0..9]) prevDigits)


(sum (map (betaRest (n - 1)) [0..9]))

Reduzcamos el número de paréntesis para poder ver mejor qué sucede.

sum (map (betaRest (n - 1)) [0..9])

El argumento de la sum es

map (betaRest (n-1)) [0 .. 9]

Ahora, betaRest :: Int -> [Int] -> Int , de ahí que el tipo de la función parcialmente aplicada es

betaRest (n-1) :: [Int] -> Int

por lo tanto, podemos inferir el tipo

map (betaRest (n-1)) :: [[Int]] -> [Int]

Pero el argumento pasado al map (betaRest (n-1)) es [0 .. 9] , que tiene

[0 .. 9] :: (Num a, Enum a) => [a]

La restricción Num proviene del uso de un literal entero, y la restricción Enum del uso de la función enumFromTo (en su forma azucarada de sintaxis [low .. high] ). Pasar eso como un argumento a una función esperando un argumento de tipo [[Int]] significa que la variable de tipo a debe ser instanciada como [Int] , y luego las restricciones deben ser verificadas, es decir, las instancias de [Int] para Num y Enum debe ser buscado. Ninguno de estos existe, de ahí los mensajes de error.

No estoy seguro de que tu ejemplo de procedimiento sea realmente lo que quieres,

int betaRest(int n, int[] prevDigits) { if (n == 0) return prevDigits.length; else { sum = 0; foreach prevDigit in prevDigits { sum += betaRest(n - 1, [0..9]); } return sum; } }

el ciclo foreach es mucho más fácil (y más eficiente) expresado como

sum = prevDigits.length * betaRest(n-1, [0 .. 9]);

prevDigit para que el foreach tenga sentido, debería haber una dependencia de prevDigit en el cuerpo del bucle.

La traducción a Haskell sería

betaRest n prevDigits | n == 0 = length prevDigits | otherwise = length prevDigits * betaRest (n-1) [0 .. 9] -- or with the loop, with the small improvement that `betaRest (n-1) [0 .. 9] -- is only computed once (if the Haskell implementation is sensible) -- | otherwise = sum $ map (const $ betaRest (n-1) [0 .. 9]) prevDigits

Pero como se dijo anteriormente, dudo que sea realmente lo que quieres.