2011-02-02 9 views
19

De los otros idiomas que programo, estoy acostumbrado a tener rangos. En Python, si quiero que todos los números sean hasta 100, escribo range(1, 101). Del mismo modo, en Haskell escribiría [1..100] y en Scala escribiría 1 to 100.Gamas en Erlang

No encuentro algo similar en Erlang, ni en la sintaxis ni en la biblioteca. Sé que esto sería bastante sencillo de implementar, pero quería asegurarme de que no existiera antes en ningún otro lugar (particularmente porque una biblioteca estándar o implementación de lenguaje sería mucho más eficiente).

¿Hay alguna manera de hacer rangos en el lenguaje de Erlang o en la biblioteca estándar? ¿O hay algún modismo que me estoy perdiendo? Solo quiero saber si debería implementarlo yo mismo.

También estoy abierto a la posibilidad de que no desee utilizar un rango en Erlang (no me gustaría codificar Python o Haskell en Erlang). Además, si yo necesito para implementar esto mismo, si tiene alguna sugerencia buena para mejorar el rendimiento, me encantaría escucharlos :)

+0

Es difícil decir si está haciendo algo incorrecto. Solo dijiste cómo intentas hacer algo, no qué estás tratando de hacer. – Dustin

+0

@Dustin Supongo que lo que quiero decir es que quiero saber si no estoy pensando como debería hacerlo en Erlang. –

+0

Como correctamente señala, listas: ¡seq/2 es el camino a seguir! Generalmente puedo recomendar mirar el módulo de listas, realmente es muy poderoso. Ah, y mira http://www.erldocs.com –

Respuesta

8

Puede utilizar list:seq(From, TO) que a decir @bitilly, y también se puede utilizar listas por comprensión para añadir más funcionalidad, por ejemplo:

1> [X || X <- lists:seq(1,100), X rem 2 == 0]. 
[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42, 
44,46,48,50,52,54,56,58|...] 
2

Hay una diferencia entre el rango de Ruby y lista: ss en Erlang. El rango de Ruby no crea una lista y depende del próximo método, por lo que (1..HugeInteger) .each {...} no consumirá memoria. Listas de Erlang: seq creará una lista (o creo que lo hará). Entonces, cuando el rango se usa para efectos secundarios, hace la diferencia.

P.S. No solo por los efectos secundarios:

(1..HugeInteger).inject(0) { |s, v| s + v % 1000000 == 0 ? 1 : 0 } 

funcionarán de la misma manera que cada uno, sin crear una lista. La forma Erlang para esto es crear una función recursiva. De hecho, es un bucle oculto de todos modos.

+0

Sí, Erlang no tiene medios para la evaluación perezosa. –

+1

@Rafe ¡Claro que sí! Solo usa diversiones. –

+0

@Daniel maldice mi juicio temprano del idioma. Debo seguir leyendo el tutorial. –

1

Ejemplo de transmisión diferida en Erlang. Aunque no es específico de Erlang, supongo que se puede hacer en cualquier idioma con lambdas. Se crea una nueva lambda cada vez que se avanza la secuencia, por lo que podría poner un poco de tensión en el recolector de basura.

range(From, To, _) when From > To -> 
    done; 
range(From, To, Step) -> 
    {From, fun() -> range(From + Step, To, Step) end}. 

list(done) -> 
    []; 
list({Value, Iterator}) -> 
    [Value | list(Iterator())]. 

% ----- usage example ------ 

list_odd_numbers(From, To) -> 
    list(range(From bor 1, To, 2)).