An infinite list is a lazily generated list with no finite endpoint. Haskell can define infinitely many values without evaluating them all, creating only the elements demanded by a consuming function. section 10.2.2 section 10.5
Use infinite lists safely by choosing operations that demand only a finite prefix:
- Create recurring values with repeat, such as repeat 1. section 10.2.2
- Generate sequences with open-ended range expressions such as [1..] or [1,3..]. section 10.2.2
- Inspect finite prefixes with take, takeWhile, (!!), or head. section 10.2.2
- Combine infinite and finite lists with zipWith or zipWith3; zipping stops when the shorter list ends. section 10.2.2
- Avoid whole-list operations such as length, which never finish on an infinite list. section 10.2.2
Building a music envelope
An ADSR envelope combines finite attack and decay curves with sus = repeat s, an infinite sustain curve, and a release curve. zipWith3 multiplies these curves with signal samples; because the signal is finite, evaluation produces only the required output. section 10.2.2
ghci> ones = 1 : ones :: [Int] ghci> take 10 ones [1,1,1,1,1,1,1,1,1,1]
Evaluate take 10 ones to observe a recursively defined infinite list without requesting the entire structure. section 10.2.2
Listing 10.8 A function to apply an ADSR envelope to a signal
import Util.Types
adsr :: ADSR -> Signal -> Signal
adsr (ADSR a d s r) signal =
zipWith3 #1
(\adsCurve rCurve sample ->
adsCurve * rCurve * sample) #1
(att ++ dec ++ sus) #2
rel
signal
where
attackSamples = fromIntegral $ samplesPerSecond a #3
decaySamples = fromIntegral $ samplesPerSecond d #3
releaseSamples = fromIntegral $ samplesPerSecond r #3
att = map (/ attackSamples) [0.0 .. attackSamples] #4
dec =
reverse $ #5
map #6
(\x -> ((x / decaySamples) * (1 - s)) + s) #6
[0.0 .. decaySamples - 1] #6
sus = repeat s #7
rel =
reverse $ #8
take #9
(length signal)
(map (/ releaseSamples) #9
[0.0 .. releaseSamples] ++ repeat 1.0) #10
Follow the complete ADSR implementation to see infinite sustain values participate in a practical signal-processing pipeline. section 10.2.2

