Подтвердить что ты не робот

Диапазоны в Эрланге

С других языков, в которые я программирую, я привык иметь диапазоны. В Python, если я хочу, чтобы все номера были до 100, я пишу range(1, 101). Точно так же в Haskell я бы написал [1..100], а в Scala написал 1 to 100.

Я не могу найти что-то подобное в Erlang, либо в синтаксисе, либо в библиотеке. Я знаю, что это было бы довольно просто реализовать самостоятельно, но я хотел убедиться, что он не существует в других местах в первую очередь (особенно, поскольку стандартная реализация библиотеки или языка будет более эффективной).

Есть ли способ делать диапазоны либо на языке Erlang, либо в стандартной библиотеке? Или есть какая-то идиома, которую мне не хватает? Я просто хочу знать, должен ли я сам реализовать его.

Я также открываю возможность того, что я не хочу использовать диапазон в Erlang (я бы не хотел кодировать Python или Haskell в Erlang). Кроме того, если мне нужно реализовать это самостоятельно, если у вас есть хорошие предложения по повышению производительности, я бы хотел их услышать:)

4b9b3361

Ответ 1

Из http://www.erlang.org/doc/man/lists.html похоже, что lists:seq(1, 100) делает то, что вы хотите. Вы также можете делать такие вещи, как lists:seq(1, 100, 2), чтобы получить все нечетные числа в этом диапазоне.

Ответ 2

Вы можете использовать list:seq(From, TO), которые говорят @bitilly, а также вы можете использовать списки, чтобы добавить больше функциональности, например:

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|...]

Ответ 3

Существует разница между диапазоном в Ruby и списком: seq в Erlang. Диапазон Ruby не создает список и полагается на следующий метод, поэтому (1..HugeInteger).each {...} не будет потреблять память. Списки Erlang: seq создаст список (или я верю, что он будет). Поэтому, когда диапазон используется для побочных эффектов, это действительно имеет значение.

P.S. Не только для побочных эффектов:

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

будет работать так же, как каждый, а не создавать список. Erlang для этого - создать рекурсивную функцию. В любом случае, это скрытый цикл.

Ответ 4

Пример ленивого потока в Эрланге. Хотя это не относится к Erlang, я думаю, это можно сделать на любом языке с лямбдами. Новая лямбда создается каждый раз, когда поток продвигается, поэтому он может наложить некоторое напряжение на сборщик мусора.

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)).