# Composing multiple functions

Last post we looked at left-to-right function composition. One idea that cropped up while I was thinking about composition was how to compose an arbitrary number of functions, say, because we’re dealing with a list of them. For this case we want to convert a list of functions [a -> a] into a single, composed function a -> a.

One approach is to fold over the list, and apply the accumulated argument to each new function. Whether we choose fold left or right will depend on the order we want the functions composed. For example, [a, b, c] can be composed right-to-left as a . b . c, or left-to-right as c . b . a.

# Left-to-right function composition

Liquid error: uninitialized constant Liquid::StandardFilters::Iconv

And so it has come to this. After learning a little bit about functors and applicative functors, I finally arrive at the notorious monad.

# FP newbie learns a little about applicatives

A few posts back I learned that functors are types that can be mapped over. The idea is that if we have a function a -> b, we would like to be able to apply that to as in different contexts, such as a list of a, a Maybe a, or an IO action that results in an a. In the previous post we referred to these contexts as "boxes", so we could lift a function a -> b to work on a box of a and return a box of b.

-- "Functor f =>"  just means that f refers to a functor type (or a type of box)
fmap :: Functor f => (a -> b) -> f a -> f b

ghci> fmap succ (Just 4)
Just 5
ghci> fmap (^2) (Just 4)
Just 16
ghci> fmap (++"!") getLine
Hello World
"Hello World!"

All these calls map single argument functions over functors, which is neat, but a bit limiting. What happens if we map a two (or more) argument function like +?

ghci> :t fmap (+) (Just 4)
fmap (+) (Just 4) :: Num a => Maybe (a -> a)

This gives us a +4 function in a Maybe context, so fmap (+) (Just 4) = Just (4+). But how do we pass the second argument to this boxed up function? We can’t use fmap again, because it’s signature takes an (a -> b), not a f (a -> b). But if f is not just a functor, but an applicative functor, then we have another option. Applicative functors still support fmap, but also add some other functions, the main one being:

(<*>) :: Applicative f => f (a -> b) -> f a -> f b

The bizarre-looking <*> function takes a boxed-up function a -> b and applies it to a boxed-up a, which is just what we need in this case.

# Towards point-free redux

Over the last two posts I’ve made a few efforts to explain how we can drop of explicit argument references when moving functions towards point-free style. We’ve looked at currying, partial function application, and function composition as explanations for this. These concepts are really important, but after kicking around various ideas about this with a colleague I’ve decided to try and separate all these concepts from the most fundamental form of reducing a function towards point-free.

# Towards point-free in C#

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:

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).

# A lengthy approach to Haskell fundamentals

At my work a few of us developers are learning Haskell, starting with some exercises from Tony Morris’s YOW workshop last year. One of these exercises involves re-implementing some common operations on lists, and this has proved a great way to learn some of the basics of Haskell.

For this post we’ll be working through implementing our own version of the length function, which takes a list and returns a integer reflecting the length of that list.

We’ll start with this non-functioning implementation, which we’ll call length' so it doesn’t collide with Haskell’s built-in function (' is a legal character to have in Haskell identifiers):

length' :: [a] -> Int
length' = error "todo"

# FP newbie learns a little about functors

As you may have noticed I’m a little obsessed with functional programming at the moment. I’ve recently been reading up on bizarre-sounding terms like functors, applicatives and monoids in Learn You A Haskell, only to discover they’re not nearly as incomprehensible as they sound. This post outlines some of the information on functors that this newbie has been able to pick up so far.

# Design via minimum code

Being a bit of a realist (;)), I find it much easier to find problems with my design ideas than I do finding designs I’m really happy with. I am always cognisant of this and make sure to balance the needs of doing a good job and getting the job done. One technique I find useful for this is thinking about the minimum amount of code required.

Whenever I find myself evaluating different design patterns or counting responsibilities to work out where the feature should go or which areas I should refactor, I stop and work out the minimum amount of code I’d need to write to solve the problem, ignoring design considerations. Once I’ve starting thinking about the problem in that light, working out where to put that code becomes a bit easier. If the code violates my sense of design aesthetics, it could just be because it is a messy problem, and no matter how hard I try to abstract or design my way out, the fundamental messiness still remains.

# Working out function types: map map

One of the exercises in Introduction to Functional Programming by Richard Bird and Philip Wadler is to work out the type signature of map map (i.e. calling map with map as its first argument). I’ve generally struggled to deal with all but the simplest of partial function application, but I found a great thread on the Lambda the Ultimate forums that really helped me out with this. Two commenters suggested different approaches: going through the maths, and understanding the abstraction.