2011-11-13 5 views
5

Así que me doy cuenta de que es un posible duplicado pregunta, ya que hay una serie de esos errores informados en Stack Overflow, pero ninguna de las soluciones parece aplicarse a mi problema.Haskell, Aunque mi tipo no se especifica me sale este error: No se puede emparejar el tipo `a 'con` [a]', `a 'es una variable de tipo rígida limitada por

Así que tienen la siguiente función:

elementAt' :: Integral b => [a] -> b -> a 
elementAt' [x:_] 1 = x 
elementAt' [x:xs] y = elementAt' xs yminus1 
    where yminus1 = y - 1 

En caso de que esté preguntando que es un problema de 3 99 Haskell Problems. El objetivo de la función es tomar como entrada una lista y un índice, y devolver el valor en ese índice (comenzando en 1). No quiero una solución al problema; si lo hiciera, podría ver los que se proporcionan. Pero me aparece un error que no entiendo. Estoy usando eclipseFP, el plugin Eclipse para Haskell y Es subrayando la "[x: _]" y "[x: xs]" porciones de la función con el siguiente error:

Couldn't match type `a' with `[a]' 
`a' is a rigid type variable bound by 
the type signature for elementAt' :: Integral b => [a] -> b -> a 

En todos los hilos que discuta este error que he observado el problema generalmente ocurre cuando alguien intenta dar un resultado incorrecto a algo que espera un cierto tipo. Por ejemplo, devolver la longitud de algo (que es de tipo Int) a lo que debería ser un tipo de variable "Num a".

Pero en mi caso ni siquiera estoy proporcionando un tipo para la variable a. Debería poder ser CUALQUIER COSA, ¿verdad? Entonces, ¿por qué estoy recibiendo este error? Si entendía por qué estaba obteniendo el error, podría solucionarlo, pero simplemente no entiendo.

¿Podría alguien explicarme por qué estoy recibiendo este error?

Su ayuda es muy apreciada, gracias. -Asaf

Editar: Todas las respuestas proporcionadas hasta el momento es correcta, gracias a todos por la útil información. Voy a elegir el que creo que es más claro (tengo que esperar 5 minutos para hacerlo).

+0

¿por qué no simplemente escribir '' elementAt '[x: xs] y = elementoAt' xs (y-1) '' –

+0

@Vixen ¿Cómo es eso diferente de lo que escribí ... aparte de incluir una declaración de variable? Obviamente, el compilador terminaría haciendo exactamente lo mismo en ambos casos (corrígeme si me equivoco). – Asaf

+0

Sí, es lo mismo, solo creo que parece extraño declarar algo como yminus1, cuando y-1 lee más fácilmente y se ve más bonito en mi opinión –

Respuesta

3

Si desea lista para la cabeza y la cola a juego, se debe utilizar

elementAt' (x:_) 1 = x 

Así que, finalmente

elementAt' :: Integral b => [a] -> b -> a 
elementAt' (x:_) 1 = x 
elementAt' (x:xs) y = elementAt' xs yminus1 
    where yminus1 = y - 1 

Y

λ> elementAt' [1,2,3] 2 
2 

¿Es lo que necesita?

1

Usar paréntesis, no paréntesis: (x:xs)

module Aaa where 

elementAt' (x:_) 1 = x 
elementAt' (x:xs) y = elementAt' xs yminus1 
    where yminus1 = y - 1 
+0

Aunque entienda la solución, es posible que no lo haga - usted no se ha dirigido '¿Podría alguien explicarme por qué estoy recibiendo este error?' –

+0

@delnan dio una explicación más arriba. Generalmente trato de dar respuestas más detalladas. – nponeccop

9

introducción de sus definición sin declaración de tipo indica que el tipo inferido es Integral b => [[a]] -> b -> a. Eso es correcto, sus patrones actuales coinciden con las listas de listas.

un patrón como

f [pat] = ... 

coincide con una lista unitaria cuyo único elemento de partidos pat. ¿Quieres trabajar con cons aka (:) en lugar de exigir a una cierta longitud, y entonces necesita paréntesis en lugar de corchetes:

elementAt' (x:xs) n = ... 

El error básicamente dice "usted trata a (los elementos del primer argumento) como si era una lista ".

+1

+1 para explicar la causa del problema, no solo para eliminar los errores. –

3

But in my case I'm not even providing a type for variable a. It should be able to be ANYTHING, right?

Tiene que ser capaz de ser cualquier cosa. Según su firma de tipo, el usuario de su función debe poder llamar a su función con a siendo Int, siendo a el [Char] o con `a'sea lo que el usuario desee.

Sin embargo, el mensaje de error le dice que ha definido su función para que solo sea posible llamarlo con a siendo una lista de algo. Es decir. usted lo definió, de modo que el primer argumento tiene que ser una lista de listas; no puede ser una lista de ninguna otra cosa. Y eso contradice tu firma de tipo.

Cuestiones relacionadas