Sequences, streams, and segments
What kind of thing is a movie? Or a song? Or a trajectory from point A to point B? If you’re a computer programmer/programmee, you might say that such things are sequences of values (frames, audio samples, or spatial locations). I’d suggest that these discrete sequences are representations of something more essential, namely a flow of continuously time-varying values. Continuous models, whether in time or space, are often more compact, precise, adaptive, and composable than their discrete counterparts.
Functional programming offers great support for sequences of variable length. Lazy functional programming adds infinite sequences, often called streams, which allows for more elegant and modular programming.
Functional programming also has functions as first class values, and when the function’s domain is (conceptually) continuous, we get a continuous counterpart to infinite streams.
Streams, sequences, and functions are three corners of a square. Streams are discrete and infinite, sequences are discrete and finite, and functions-on-reals are continuous and infinite. The missing corner is continuous and finite, and that corner is the topic of this post.
infinite | finite | |
discrete | Stream | Sequence |
continuous | Function | ??? |
You can download the code for this post.
Edits:
- 2008-12-01: Added Segment.hs link.
- 2008-12-01: Added
Monoid
instance for function segments. - 2008-12-01: Renamed constructor “
DF
” to “FS
” (for “function segment”) - 2008-12-05: Tweaked the inequality in
mappend
on(t :-># a)
.