無限ストリーム
無限に続くデータを安全にモデル化します。
「無限ストリーム」はCoddyKit上の無料Scala for Backend Engineering & Functional Programmingレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはScala for Backend Engineering & Functional Programming学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。
このレッスンの一部はまだ翻訳されておらず、英語で表示されています。
Infinity, Safely
A LazyList can describe an infinite sequence because its tail is never computed until demanded. You only ever materialize the prefix you consume.
This lets you model natural numbers, primes, or sensor readings without bounding them up front.
All Natural Numbers
LazyList.from(1) is the infinite sequence 1, 2, 3, ... You can take any finite prefix.
Forcing the whole thing would never finish, so always slice it with take or stop with a predicate.
object Demo extends App {
val nats = LazyList.from(1)
println(nats.take(5).toList)
}from with a Step
LazyList.from(start, step) counts by an interval. Use it for even numbers, ticks, or any arithmetic progression.
The sequence is infinite but each call to take forces only what you ask for.
object Demo extends App {
val evens = LazyList.from(0, 2)
println(evens.take(5).toList)
}Self-Referential Streams
A famous trick: define a LazyList in terms of itself. The Fibonacci sequence can be written by zipping the stream with its own tail.
This works only because the tail stays unevaluated until each cell is pulled.
lazy val fibs: LazyList[Int] =
0 #:: 1 #:: fibs.zip(fibs.tail).map { case (a, b) => a + b }
// fibs(0)=0, fibs(1)=1, fibs(2)=1 ...Running Fibonacci
Let's force a prefix of that self-referential Fibonacci stream.
Each new element is computed from earlier, already-memoized ones, so the whole thing stays efficient as you pull more values.
object Demo extends App {
lazy val fibs: LazyList[Int] =
0 #:: 1 #:: fibs.zip(fibs.tail).map { case (a, b) => a + b }
println(fibs.take(10).toList)
}iterate for Sequences
LazyList.iterate generates an infinite sequence by a step function. Powers, geometric growth, and state machines fit naturally.
Here each element is triple the previous, forever.
object Demo extends App {
val triples = LazyList.iterate(1)(_ * 3)
println(triples.take(6).toList)
}A Prime Sieve
Infinite streams shine for the Sieve of Eratosthenes. Take a head prime, filter its multiples from the rest, and recurse.
The filter is lazy, so primes are produced one at a time as you consume them.
def sieve(s: LazyList[Int]): LazyList[Int] =
s.head #:: sieve(s.tail.filter(_ % s.head != 0))
val primes = sieve(LazyList.from(2))Running the Sieve
Now pull the first ten primes from that infinite sieve.
Only enough of the underlying number stream is forced to yield ten primes, demonstrating demand-driven computation.
object Demo extends App {
def sieve(s: LazyList[Int]): LazyList[Int] =
s.head #:: sieve(s.tail.filter(_ % s.head != 0))
val primes = sieve(LazyList.from(2))
println(primes.take(10).toList)
}Never Force the Whole Thing
Methods that need the entire sequence, like length, toList on an unbounded stream, or foreach without a stop, will hang on an infinite LazyList.
Always bound first with take, takeWhile, or find.
// DON'T: LazyList.from(1).toList // hangs forever
val ok = LazyList.from(1).take(3).toListThe Head-Holding Trap
If a val holds the head of an infinite memoizing LazyList and you consume far into it, every forced cell stays alive, leaking memory.
For long traversals, consume via a method without binding the head, or use an Iterator.
Why Infinite Streams Matter
Infinite streams let you separate generation from consumption. The producer describes an endless rule; the consumer decides how much to realize.
This is a powerful functional pattern for pipelines, simulations, and lazy data sources.
Quick Check
Test your understanding of infinite LazyLists.
Recap
Infinite LazyLists work because the tail is demand-driven: from, iterate, self-referential fibs, and the prime sieve all generate endlessly yet realize only what you consume.
Avoid whole-sequence operations and head-holding. Next, we master taking and filtering lazily.
よくある質問
「無限ストリーム」レッスンは無料ですか?
はい。「無限ストリーム」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Scala for Backend Engineering & Functional Programmingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。
「無限ストリーム」で何を学びますか?
無限に続くデータを安全にモデル化します。 ブラウザで直接実行するハンズオンコードでScala for Backend Engineering & Functional Programmingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Scala for Backend Engineering & Functional Programmingを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのScala for Backend Engineering & Functional Programmingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「無限ストリーム」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このScala for Backend Engineering & Functional Programmingレッスンでコードを書いて実行できますか?
はい。すべてのScala for Backend Engineering & Functional Programmingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。