- declaratively design complicated program flows
- use recursion and laziness to defer some decisions
- handle IO-based streams of data
- create and handle infinite stream of values
- isolate time-dependent functionalities
Thinking is not the ability to manipulate language; it’s the ability to manipulate concepts.
9.1 To infinity and beyond
We have just learned how to read and write data using IO. In this chapter we will still use IO to represent our side-effectful programs as values, but our data will become much bigger, possibly infinite.
9.2 Dealing with an unknown number of values
9.3 Dealing with external impure API calls (again)
9.4 The functional approach to the design
9.5 Immutable maps
9.6 Practicing immutable maps
9.7 How many IO calls should we make?
9.8 The bottom-up design
9.9 Advanced list operations
9.10 Introducing tuples
9.11 Zipping and dropping
9.12 Pattern matching on tuples
9.13 Coffee Break: Working with maps & tuples
9.14 Coffee Break Explained: Working with maps & tuples
9.15 Functional jigsaw puzzle
9.16 Following types in a bottom-up design
9.17 Prototyping and dead ends
9.18 Recursive functions
9.19 Infinity and laziness
9.20 Recursive function structure
9.21 Dealing with an absence in the future (using recursion)
9.22 Usefulness of infinite recursive calls
9.23 Coffee Break: Recursion and infinity
9.24 Coffee Break Explained: Recursion and infinity
9.25 Creating different IO programs using recursion
9.26 Using recursion to make an arbitrary number of calls
9.27 Problems with the recursive version
9.28 Introducing data streams
9.29 Streams in imperative languages
9.30 Values on demand
9.31 Stream processing, producers and consumers
9.32 Streams and IO