Last post we saw an example of writing a function to get the length of a list, first using explicit recursion, then folds, then moving towards point-free style by dropping explicit references to arguments where practical. To summarise the latter part of that post:
length xs = foldl' (\acc x -> acc+1) 0 xs
length = foldl' (\acc x -> acc+1) 0 -- `xs` appears on both sides, so can drop it.
length = foldl' (\acc x -> const (acc+1) x) 0 -- `const` ignores 2nd arg, returns 1st.
length = foldl' (\acc -> const (acc+1)) 0 -- Drop `x` from both sides of lambda
length = foldl' (\acc -> const (succ acc)) 0 -- Replace (+1) with built-in `succ` function
length = foldl' (\acc -> (const.succ) acc) 0 -- Function composition rule: (f.g) x = f(g x)
length = foldl' (const.succ) 0 -- Drop `acc` from both sides of lambda
The topic of this post is the "argument appears on both sides so can drop it" steps. How do we go from passing foldl' a function which takes two explicit arguments (\arg x -> ...) to none? The answer is by using currying, partial function application and function composition, and we can do both of these in C# (albeit not as neatly, as C# is not really built for it).