2014-09-26 6 views
7

Mi sto allenando per un test domani per completare la mia introduzione alla programmazione funzionale, ma c'è una cosa che non capisco.Haskell: modelli non esaustivi

Ogni volta che ho un programma come:

test [] = [] 
test (x:xs) = test (xs) 

Quello che fa è che si prende il primo elemento fuori dalla lista e continua con il resto. Ogni volta che ne rimane una sola, xs dovrebbe essere [] che a sua volta dovrebbe attivare test [] = []. Ma ogni volta che eseguo questo algoritmo ottengo un errore. Exception: <interactive>:20:5-16: Non-exhaustive patterns in function test.

Non sono riuscito a trovare una spiegazione chiara online. Qualcuno potrebbe mandarmi un link per spiegarlo chiaramente o spiegarmelo?

+1

Strano. Lo snippet di codice che hai pubblicato non contiene pattern non esaustivi. – pyon

+1

Solo riprese al buio: stai forse cercando di inserire questa definizione in ghci? Se è così, dovresti usare una sola istruzione let: 'let test [] = []; test (x: xs) = test xs'. – pyon

+0

Sì, è quello che sto facendo. Grazie mille. Ho già iniziato a dare di matto perché ho passato tutta la settimana a programmare le ricorsioni e non sono riuscito a capire perché questo non avrebbe funzionato. –

risposta

24

Il codice inserito nel corpo della domanda corrisponde al modello completo. Tuttavia, se si tenta di entrare in questa definizione nella ghci, è necessario utilizzare una dichiarazione singololet:

Prelude> let test [] = [] ; test (x:xs) = test xs 

Quello che state facendo here non è corretto. Si sono prima definizione di una funzione non esaustivo test:

Prelude> let test [] = [] 

E poi si sta definendo un'altra funzione non esaustivo, chiamato anche test, che nasconde la prima:

Prelude> let test (x:xs) = test xs 
+1

Vorrei poter sopravvivere altre volte. –

4

Questo è davvero una cosa molto complicata di provare i programmi per bambini in REPL di Haskell (GHCi).

L'utilizzo di let non è molto evidente (specialmente perché non è necessario in uno "script/programma" separato).

E a volte NON vogliamo creare un file a tutti gli effetti, ma sperimentare con una piccola funzione con diversi "casi".

Un altro approccio utile consiste nell'utilizzare i delimitatori :{ & :} per definire l'estensione della nostra funzione.

Dire che vogliamo provare una semplice funzione ricorsiva sum che può aggiungere un elenco di numeri. Vorremmo quindi dire quanto segue:

λ > :{ 
Prelude| sum [] = 0 
Prelude| sum (x:xs) = x + sum xs 
Prelude| :} 
sum :: Num t => [t] -> t 
Prelude 
λ > sum [1..10] 
55 
it :: (Enum t, Num t) => t 

Nota come possiamo vedere ora l'estensione della nostra funzione!

Spero che questo aiuti. Saluti!