Создание LazyList
Создавайте ленивые последовательности.
«Создание LazyList» — бесплатный урок Scala for Backend Engineering & Functional Programming на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Scala for Backend Engineering & Functional Programming, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.
Основы создания
Создать LazyList можно несколькими способами. Самый простой — фабрика apply, как при создании List.
Но настоящая сила заключается в конструкторах, сохраняющих ленивость хвоста. Их мы и рассмотрим в этом уроке.
val ll = LazyList(10, 20, 30)
println(ll.head)Пустой LazyList
LazyList.empty — завершающий элемент, ленивый аналог Nil. Им заканчивается каждый конечный LazyList.
Используйте его как базовый случай при добавлении элементов в начало с помощью #::.
object Demo extends App {
val empty = LazyList.empty[Int]
println(empty.isEmpty)
println(empty.toList)
}Добавление в начало с помощью #::
Оператор #:: добавляет голову к хвосту, передаваемому по имени. Стройте список справа налево, завершая его значением LazyList.empty.
Поскольку #:: принимает хвост лениво, всё после головы не создаётся до принудительного вычисления.
object Demo extends App {
val ll = 1 #:: 2 #:: 3 #:: LazyList.empty
println(ll.toList)
}Наблюдаем за ленивостью
Добавьте побочный эффект в хвост, чтобы увидеть, когда он выполняется. Только принудительное вычисление хвоста запускает его.
Запустите этот код: «building tail» выводится только после обращения ко второму элементу, а не при объявлении LazyList.
object Demo extends App {
val ll = 1 #:: { println("building tail"); 2 #:: LazyList.empty }
println("defined")
println(ll.head)
println(ll(1))
}Явный вызов cons
Внутри #:: является LazyList.cons. И голова, и хвост в cons передаются по имени, что даёт полный контроль над вычислениями.
Это полезно при определении рекурсивных генераторов.
val ll = LazyList.cons(1, LazyList.cons(2, LazyList.empty))
println(ll.head)Рекурсивные генераторы
LazyList может ссылаться сам на себя. Определите функцию, создающую голову и рекурсивно вызывающую себя для хвоста.
Поскольку хвост передаётся по имени, рекурсия не выполняется бесконечно: она приостанавливается, пока не потребуется очередная ячейка.
def countFrom(n: Int): LazyList[Int] =
n #:: countFrom(n + 1)
println(countFrom(5).take(3).toList)Запуск генератора
Запустим генератор, ссылающийся сам на себя, и получим несколько значений. take ограничивает количество принудительно вычисляемых ячеек.
Без take этот код зациклился бы навсегда, поэтому всегда ограничивайте бесконечный генератор перед принудительным вычислением.
object Demo extends App {
def countFrom(n: Int): LazyList[Int] =
n #:: countFrom(n + 1)
println(countFrom(1).take(5).toList)
}Из итератора
Вы можете обернуть существующую коллекцию или итератор. LazyList.from(start) создаёт бесконечный ряд чисел, а someList.to(LazyList) преобразует уже известные данные.
Это даёт ленивое представление данных, которые у Вас уже есть или которые Вы можете описать.
object Demo extends App {
val ll = List(1, 2, 3).to(LazyList)
println(ll.map(_ * 2).toList)
}LazyList.iterate
LazyList.iterate(seed)(f) многократно применяет f, создавая каждый следующий элемент на основе предыдущего.
Это удобный способ выразить последовательности, заданные правилом перехода, например степени двойки.
object Demo extends App {
val powers = LazyList.iterate(1)(_ * 2)
println(powers.take(6).toList)
}LazyList.continually
LazyList.continually(expr) бесконечно повторяет выражение, заново вычисляя его для каждого элемента. Это удобно для постоянных или случайных потоков.
Объедините его с take, чтобы получить конечный фрагмент.
object Demo extends App {
val zeros = LazyList.continually(0)
println(zeros.take(4).toList)
}Выбор конструктора
Используйте apply для небольших списков фиксированного размера, #:: или cons для рекурсии, записанной вручную, iterate для правил перехода, from для счёта и continually для повторения.
Все они сохраняют ленивость хвоста, поэтому выбор зависит от выразительности.
Быстрая проверка
Проверьте, насколько хорошо Вы усвоили создание LazyList.
Итоги
Вы создавали LazyLists с помощью apply, empty, #::/cons, iterate, from и continually.
Хвост, передаваемый по имени, позволяет безопасно определять самоссылочные потенциально бесконечные генераторы. Далее мы используем это, чтобы создавать действительно бесконечные потоки.
Часто задаваемые вопросы
Урок «Создание LazyList» бесплатный?
Да — полный текст урока «Создание LazyList» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Scala for Backend Engineering & Functional Programming, подпишись на CoddyKit PRO. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.
Чему я научусь в уроке «Создание LazyList»?
Создавайте ленивые последовательности. Ты практикуешь Scala for Backend Engineering & Functional Programming с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Scala for Backend Engineering & Functional Programming?
Предыдущий опыт не требуется. Scala for Backend Engineering & Functional Programming на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Создание LazyList»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Scala for Backend Engineering & Functional Programming?
Да. Каждый урок Scala for Backend Engineering & Functional Programming включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.