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

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

23 голосов
/ 02 февраля 2011

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

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

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

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

Ответы [ 4 ]

53 голосов
/ 02 февраля 2011

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

11 голосов
/ 02 февраля 2011

Вы можете использовать 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|...]
2 голосов
/ 04 февраля 2011

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

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

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

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

1 голос
/ 04 июня 2013

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

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)).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...