2012-06-21 23 views
6

Implemente una lista de comprensión de Erlang que toma dos elementos de una lista y hace una nueva lista de listas.Erlang: ¿cómo implementar la comprensión de listas de Erlang?

tengo este código

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

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

que funciona muy bien:

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

pero parece que debería ser capaz de implementar esto como una lista por comprensión. Mi Erlang-fu es demasiado débil para pensarlo.

¿Alguna sugerencia?

Gracias

Respuesta

1

Una lista por comprensión será torpe, ya que inevitablemente tiene que hacer algo para cada elemento de la lista. Para crear una lista de comprensión, debe intentar averiguar si se trata de un elemento par o impar con el que está hablando. He aquí una idea de lo que estoy hablando:

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 complejidad del tiempo en este caso es probablemente horrible, porque por lo que yo soy consciente de Erlang no optimiza esto de ninguna manera.

No creo que haya nada de malo en tu función y deberías atenerse a ella.

8

No, una lista de comprensión no sería una buena manera de hacerlo, por definición, solo trabajan en un elemento a la vez. En su código, realmente no es necesario usar un acumulador, la diferencia de velocidad es pequeña, here, y se vuelve más claro sin ella. Al menos yo lo pienso.

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

Esto sigue al mantra de Erlang "let it crash", p. para el caso '[a]'. – Tilman

+0

@Tilman Sí, la función está ** definida ** para tomar pares de elementos, por lo que si es un error si hay un número impar de elementos en la lista. Por supuesto, siempre puedes definir lo que sucederá en ese caso y manejarlo después de eso. – rvirding