Working with program state is tricky, and even more so in functional programming, where we value principles such as immutability and eradicating side effects. Mutating state comes at a considerable cost, making programs difficult to reason about and maintain. Fortunately, we have a design pattern at hand to deal with program state in a purely functional way. Applying this pattern allows us to deal with state in a deterministic fashion and subsequently lets us reason about and test our programs more easily.
By viewing the program state as a transition or action that is passed along as context during a series of transformations, we can contain and localize the complexity associated with state machines. We can even take this a step further by hiding these state transitions altogether through the use of higher-order combinator functions that pass along state actions implicitly in the background. A pattern begins to emerge as we combine these concepts of passing and hiding state transitions in the background.