2013-08-19 12 views
8

Contro non sembra funzionare come mi aspetterei nel secondo esempio. Cosa mi manca?Come funziona cons in Haskell:

Qui cons aggiunge un elemento a un elenco, che è grande.

1:[2,3] 

Ma con questo sembra mettere il primo elemento nella lista x e la coda in xs lista:

let { myInt :: [Int] -> [Int] ; myInt (x:xs) = xs } 

io non vedo proprio il motivo per cui questo sarebbe accaduto, è qualcosa di fare con la ricorsione?

Grazie in anticipo!

+2

E 'bello ricordare che haskell98 consente * costruttori di infisso * tipo, che deve iniziare con "': '", quindi la lista cons costruttore (che prende due argomenti) è un caso un po' particolare di questa regola generale. – jberryman

risposta

11

L'operatore : può essere utilizzato sia per costruzione un elenco e decostruire un elenco, a seconda di dove lo si utilizza. Se lo usi in un'espressione, è usato per costruire una lista, proprio come hai detto tu. Quando lo usi in un modello, fa il contrario: decostruisce (separa) un elenco.

Costruire una lista:

λ> 1:2:[3, 4] 
[1,2,3,4] 

Decostruire un elenco:

λ> let first:second:rest = [1, 2, 3, 4] 
λ> first 
1 
λ> second 
2 
λ> rest 
[3, 4] 

Lo stesso vale per molti costruttori di dati in Haskell. È possibile utilizzare Just per creare un valore Maybe.

λ> let name = Just "John" 
λ> :type name 
name :: Maybe [Char] 

Tuttavia, si potrebbe anche usare per smontare un valore Maybe.

λ> let Just x = name 
λ> x 
"John" 
+0

Nota che non c'è nulla di "speciale" su ':' qui; Tutti i costruttori di valore hanno questa proprietà. – MathematicalOrchid

9

Ci sono due cose diverse che accadono qui. Il primo esempio utilizza l'operatore (:) per creare un nuovo elenco dall'elemento 1 e dall'elenco [2,3].

1:[2,3] 

tuo secondo esempio utilizza pattern matching. L'espressione ...

myInt (x:xs) = ... 

... essenzialmente dice "se l'argomento di myInt costituito da un elemento preposto ad una lista (eventualmente vuoto), quindi Chiamiamo il primo elemento x e l'elenco xs". Questo esempio può essere più chiaro:

λ> let { myInt :: [Int] -> String ; myInt (x:xs) = "The first element is " ++ show x ++ " and the rest of the list is " ++ show xs} 
λ> myInt [1,2,3] 
"The first element is 1 and the rest of the list is [2,3]" 

Si noti che questo funzionerà solo se l'elenco di input contiene almeno un elemento.

λ> myInt [] 
"*** Exception: <interactive>:9:34-127: Non-exhaustive patterns in function myInt 

Possiamo comunque gestire il caso in cui la lista di input è vuota simili:

λ> let { myInt :: [Int] -> String ; myInt (x:xs) = "The first element is " ++ show x ++ " and the rest of the list is " ++ show xs; myInt _ = "empty list"} 
λ> myInt [] 
"empty list" 
Problemi correlati