2010-03-30 9 views

risposta

39
pairs [] = [] 
pairs xs = zip xs (tail xs) 
+21

si dovrebbe essere ok con solo la seconda linea dal 'zip [] undefined' è' [] ' – rampion

+0

Oh, hai ragione. Non ci ho pensato. –

+0

@rampion: è davvero necessario sapere come funziona lo zip internamente per sapere che questo è il caso e significherebbe che zip (tail xs) xs non funzionerebbe. Questo non sembra un buon modo per scrivere codice chiaro e ovvio. –

6

Solo per completezza, una versione più "a basso livello" con esplicito ricorsione:

pairs (x:[email protected](y:_)) = (x, y) : pairs xs 
pairs _   = [] 

Il costrutto x:[email protected](y:_) mezzi " un elenco con una testa x e una coda xs con almeno un elemento ". Questo perché raddoppia come sia il secondo elemento della coppia corrente sia il primo elemento del successivo. In caso contrario, avremmo dovuto fare un caso speciale per liste di lunghezza 1.

pairs [_] = [] 
pairs [] = [] 
pairs (x:xs) = (x, head xs) : pairs xs 
+4

'coppie (x: y: resto) = (x, y) : pairs (y: rest) 'funzionerebbe anche, evitando la necessità di' @ ', anche se a costo di un costruttore aggiuntivo. – ephemient

20

Si potrebbe andare per quanto

import Control.Applicative (<*>) 
pairs = zip <*> tail 

ma

pairs xs = zip xs (tail xs) 

è probabilmente più chiara.

+1

Ottimo! Sono un principiante, quindi mi ci sono voluti 30 minuti per capire perché 'zip <*> tail' funziona, ma ne è valsa la pena. Se anche qualcun altro è curioso, dai un'occhiata qui: http://stackoverflow.com/questions/11810889/functions-as-applicative-functors-haskell-lyah e, ​​nel processo, leggi il capitolo 11 di LYAH. Bella citazione: _ "Un'altra istanza di Applicative è (->) r, quindi funzioni. Sono raramente utilizzate con lo stile applicativo al di fuori del codice golf [...]" _ – Bolo

+0

Come per pointfree.io, 'pairs = ap zip tail' funziona anche, come 'ap' è come' <*> 'ma per le monadi. – Caridorc

2

Chiama per il dio azteco di numeri consecutivi:

import Control.Monad (ap) 
import Control.Monad.Instances() -- for Monad ((->) a) 

foo = zip`ap`tail $ [1,2,3,4] 
Problemi correlati