2011-11-13 8 views
5

Quindi mi rendo conto che questo è un possibile duplicato domanda, in quanto vi è un numero di tali errori riportati su Stack Overflow, ma nessuna delle soluzioni sembra applicarsi al mio problema.Haskell, Anche se il mio tipo non è specificato ottengo questo errore: Impossibile trovare il tipo `a 'con` [a]', 'a' è una variabile di tipo rigida vincolata da

così ho la seguente funzione:

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

Nel caso vi stiate chiedendo che è problema da 3 99 Haskell Problems. L'obiettivo della funzione è di prendere come input un elenco e un indice e restituire il valore in quell'indice (a partire da 1). Non voglio una soluzione al problema, se lo facessi potrei semplicemente guardare quelli forniti. Ma sto ricevendo un errore che non capisco. Sto utilizzando eclipseFP, il plugin Eclipse per Haskell e sta sottolineando il "[x: _]" e "[x: xs]" porzioni della funzione con il seguente errore:

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 

In tutte le discussioni che discuto di questo errore che ho osservato il problema si verifica in genere quando qualcuno tenta di dare un output errato a qualcosa che si aspetta un certo tipo. Ad esempio, restituendo la lunghezza di qualcosa (che è di tipo Int) a quello che dovrebbe essere un tipo di variabile "Num a".

Ma nel mio caso non sto nemmeno fornendo un tipo per la variabile a. Dovrebbe essere in grado di essere QUALCOSA, giusto? Allora, perché sto ricevendo questo errore? Se ho capito perché stavo ottenendo l'errore, potrei risolverlo, ma non capisco.

Qualcuno potrebbe spiegarmi perché sto ricevendo questo errore?

Il vostro aiuto è molto apprezzato, grazie. -Asaf

Modifica: Ogni risposta fornita finora è corretta, grazie a tutti per le informazioni utili. Vado a scegliere quello che credo sia più chiaro (devo aspettare 5 minuti per farlo però).

+0

perché non scrivere semplicemente '' elementAt '[x: xs] y = elementAt' xs (y-1) '' –

+0

@Vixen Quanto è diverso da ciò che ho scritto ... oltre ad includere una dichiarazione di variabile? Ovviamente il compilatore finirebbe per fare la stessa identica cosa in entrambi i casi (correggimi se sbaglio). – Asaf

+0

Sì, è lo stesso, penso che sia strano dichiarare qualcosa come yminus1, quando y-1 si legge più facilmente e sembra più bello secondo me –

risposta

3

Se si desidera lista di testa e la coda di corrispondenza, è necessario utilizzare

elementAt' (x:_) 1 = x 

Così, finalmente

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

E

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

E 'quello che ti serve?

1

Utilizzare le parentesi, non parentesi: (x:xs)

module Aaa where 

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

Sebbene tu possa capire la soluzione, il richiedente non può - non hai risposto 'Qualcuno potrebbe spiegarmi perché sto ricevendo questo errore?' –

+0

@delnan ha fornito una spiegazione sopra. In genere cerco di dare risposte più dettagliate. – nponeccop

9

Inserimento definizione senza dichiarazione di tipo indica che il tipo dedotto è Integral b => [[a]] -> b -> a. È corretto, i tuoi schemi attuali corrispondono a elenchi di elenchi.

Un modello come

f [pat] = ... 

corrisponde un elenco Singleton il cui unico elemento partite pat. Si desidera lavorare con cons aka (:) invece l'esigenza che una certa lunghezza, e quindi è necessario parentesi invece di staffe:

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

L'errore dice sostanzialmente "si trattano a (gli elementi del primo argomento) come se era una lista ".

+1

+1 per spiegare la causa del problema, non solo per far sparire gli errori. –

3

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

Deve essere in grado di essere qualsiasi cosa. In base alla firma del tipo, l'utente della funzione deve essere in grado di chiamare la propria funzione con aInt, con a[Char] o con "a" essere qualsiasi altra cosa l'utente desideri.

Tuttavia, il messaggio di errore indica che è stata definita la funzione in modo che sia possibile chiamarla con a come elenco di qualcosa. Cioè lo hai definito, in modo che il primo argomento debba essere una lista di liste - non può essere un elenco di nient'altro. E questo contraddice la tua firma del tipo.

Problemi correlati