Последовательность против LazyList - PullRequest
16 голосов
/ 09 февраля 2012

Я не могу обернуть голову вокруг различий между последовательностью и LazyList.Они оба ленивы и потенциально бесконечны.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * LazyList не содержит *1004*, а *1004* - это IEnumerable<'T> из .NET Framework.На практике я сталкиваюсь с последовательностями гораздо чаще, чем LazyList с.

В чем их различия с точки зрения производительности, использования, читаемости и т. Д.?Каковы причины такой плохой репутации LazyList по сравнению с seq?

Ответы [ 2 ]

31 голосов
/ 09 февраля 2012

LazyList вычисляет каждый элемент только один раз, независимо от того, сколько раз был пройден список. Таким образом, это ближе к последовательности, возвращаемой из Seq.cache (а не к типичной последовательности). Но, кроме кэширования, LazyList ведет себя точно так же, как список: он использует структуру списка внутри и поддерживает сопоставление с образцом. Поэтому вы можете сказать: используйте LazyList вместо seq, когда вам нужна семантика списка и кэширование (в дополнение к лени).

Что касается того, что оба бесконечны, seq использование памяти является постоянным, а LazyList - линейным.

Эти документы могут стоить прочитать.

19 голосов
/ 09 февраля 2012

В дополнение к ответу Даниэля, я думаю, что основное практическое отличие состоит в том, как вы обрабатываете LazyList или seq структуры (или вычисления).

  • Если вы хотите обработать LazyList, вы обычно пишете рекурсивную функцию с использованием сопоставления с образцом (очень похоже на обработку обычных списков F #)

  • Если вы хотите обработать seq, вы можете использовать встроенные функции или написать императивный код, который вызывает GetEnumerator, а затем использовать возвращенный перечислитель в цикле (который может быть записан как рекурсивная функция, но она будет мутировать перечислитель). Вы не можете использовать обычный стиль головы / хвоста (используя Seq.tail и Seq.head), потому что это крайне неэффективно - потому что seq не сохраняет оцененные элементы, и результат Seq.head должен повторяться из начать.

Что касается репутации seq и LazyList, я думаю, что дизайн библиотеки F # использует прагматичный подход - поскольку seq на самом деле .NET IEnumerable, он довольно удобен для программирования .NET ( также приятно, потому что вы можете относиться к другим коллекциям как seq). Ленивые списки встречаются не так часто, поэтому в большинстве случаев достаточно обычного списка F # и seq.

...