Последовательность против LazyList

Я не могу обернуть голову вокруг различий между последовательностью и LazyList, Они оба ленивы и потенциально бесконечны. В то время как seq<'T> является IEnumerable<'T> из.NET Framework, LazyList входит в F# PowerPack. На практике я встречаю последовательности намного чаще, чем LazyList s.

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

2 ответа

Решение

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

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

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

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

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

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

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

Другие вопросы по тегам