The central idea in this book is the importance of recursion patterns in functional programming. One of the simplest examples is the map operator on lists, defined in Haskell as follows:
(Intuitively, applies a function to every element of a list, returning a new list. When is applied to the empty list , it returns the empty list; applied to a non-empty list with head and tail , it returns the list whose head is applied to , and whose tail is applied recursively to . Because the function accepts another function as an argument, it is called a higher-order function.)
Another example familiar to Haskell programmers is the fold operator on lists:
(Intuitively, this “folds” a list up into a value; the empty list is folded into the initial value , and a non-empty list is folded by recursively folding the tail then combining the result of this with the head using the binary function .)
One can think of the operators and as abstracted patterns of computation: many useful functions can be expressed in terms of them, and identifying them as useful and reusable concepts saves a lot of repetition in code. Put another way, functional programming (especially lazy functional programming) languages provide the programmer with good tools for building their own control structures; if you don’t have the right kind of loop built-in, just define it as a higher-order function.
But there’s another benefit to be derived from certain recursion patterns (in particular, for the map and fold above, but not for any old custom control structure that you might just have defined). Take the definition of , but abstract from the part:
and read this as an equation in the unknown , for fixed and . It turns out that this equation has a unique solution (modulo some subtleties, as we’ll cover later) — which is, as you might have guessed, . This is called the universal property of , and it is very convenient for reasoning about programs with. For example, to show that some complicated expression equals a given fold, it suffices to show that the expression satisfies the universal property for that fold. Such universal properties will come up again and again throughout the book.
http://conal.net/blog/posts/functional-reactive-partner-dancing/
recursion … a sort of strip the willow?
Might it be helpful to the reader if the type signatures are included in the code fragments?
It might be clearer to specify in the ‘map’ example that f : a -> a, and in the ‘foldr’ example that f : a -> b -> b.
Yes, including the types would have been helpful – thanks! But note that for map, f can have type a->b for different a and b.
Which book do you refer to ‘this book’?
Excellent question! I started the blog with the ambition of writing a book with the same title. Obviously I haven’t succeeded in that goal…