2012-06-21 5 views
6

Implementare una comprensione di lista Erlang che prende due elementi da un elenco e crea un nuovo elenco di elenchi.Erlang: come implementare la comprensione delle liste di Erlang?

Ho questo codice

pair([], Acc) -> lists:reverse(Acc); 

pair(L, Acc0) -> 
    [ A, B | T ] = L, 
    Acc = [ [A, B] | Acc0 ], 
    pair(T, Acc). 

che funziona bene:

7> l:pair(lists:seq(1,6), []). 
[[1,2],[3,4],[5,6]] 

ma sembra che dovrei essere in grado di implementare questa come una lista di comprensione. Il mio Erlang-fu è troppo debole per inventarlo.

Qualche suggerimento?

Grazie

risposta

1

un elenco di comprensione sarà goffo perché inevitabilmente deve fare qualcosa per ogni elemento della lista. Per creare una comprensione delle liste devi quindi cercare di scoprire se si tratta di un elemento pari o dispari con cui stai parlando. Ecco un'idea di che cosa sto parlando:

pair(L) -> 
    L2 = lists:zip(lists:seq(1, length(L)), L), 
    [[A, B] || {Ai, A} <- L2, {Bi, B} <- L2, 
      Ai rem 2 == 1, Bi rem 2 == 0, Ai + 1 == Bi]. 

La complessità tempo su questo è probabilmente orribile perché per quanto io sappia Erlang non ottimizzare questo in alcun modo.

Non penso che ci sia qualcosa di sbagliato nella vostra funzione e dovreste attenervisi.

8

No, una comprensione delle liste non sarebbe un buon modo per farlo, per definizione funzionano solo su un elemento per volta. Nel tuo codice non c'è davvero bisogno di usare un accumulatore, la differenza di velocità è piccola, here, e diventa più chiara senza di essa. Penso di sì almeno.

pairs([A,B|L]) -> 
    [[A,B]|pairs(L)]; 
pairs([]) -> []. 
+1

Questo segue il mantra di Erlang "lasciarlo cadere", ad es. per il caso "[a]'. – Tilman

+0

@Tilman Sì, la funzione è ** definita ** per prendere coppie di elementi, quindi se si tratta di un errore se c'è un numero dispari di elementi nell'elenco. Ovviamente potresti sempre definire cosa deve succedere in quel caso e gestirlo dopo. – rvirding