Although tail recursion and modules allow us to get more out of the functional style of programming, there is still more we can learn about functions as values. Next, we will look at function currying and closures. While they may not be the most important aspect of functional programming, having a good understanding of their capabilities will make it easier for you to write code in the purely functional style.
Recall that function currying is the ability to specify a subset of a function’s parameters and return new functions taking fewer parameters. On the surface, this seems like a strange feature to add. What does only providing a subset of a function’s parameters actually buy you? The most visible benefit of function currying is the pipe-forward operator, which makes data transformation much more elegant:
getCustomers() |> List.filter (fun cust -> datesEqual cust.Birthday DateTime.Today) |> List.map (fun cust -> cust.EmailAddress) |> List.filter Option.isSome |> sendSpam "Happy Birthday... Now buy our product!"
Each line of the previous expression is a curried function whose last parameter is provided by the previous line of code. Writing code in this style enables you to write code exactly the way you conceptualize it in your head. But function currying has another way of cleaning up your code as well.
Using function currying can potentially eliminate the need for many lambda expressions. Consider the following code, ...