F#: Composition and Partial Application

Intro

I recently returned to my Game of Life implementation after taking two weeks off. Upon returning, I observed certain pieces of code that jumped out at me. Specifically, I observed some minor duplication of function calls.

let updateCells (grid:Map<(int * int), Cell>) =
 
    grid |> Map.toSeq
         |> Seq.map snd
         |> Seq.fold (fun grid c -> grid |> setReaction (c.X, c.Y)) grid

let mutable _cells = ObservableCollection<Cell>( grid |> Map.toSeq
                                                      |> Seq.map snd
                                                      |> Seq.toList )
let cycleHandler _ = 
 
    self.Cells <- ObservableCollection<Cell>( grid |> cycleThroughCells
                                                   |> Map.toSeq
                                                   |> Seq.map snd
                                                   |> Seq.toList )

If you’ve noticed, the following code appears in all three functions:

grid |> Map.toSeq
     |> Seq.map snd

This is only two lines of code. However, I often challenge myself to reduce the footprint that I leave for my clients. I guess my thought process is analogous to a surgeon that wants to leave the smallest scar possible when performing surgery.

So how can we resolve this duplication of code?

Function Composition

Within functional programming, we can fuse functions together so that they can become one function.

To do this, let’s create a new function from the duplicated sequence of functions:

let getCells = Map.toSeq >> Seq.map snd >> Seq.toList

Now if you’re attentive, you will have noticed that we don’t use any arguments when using Function Composition. Hence, the grid value is not used. The reason behind this is because of Partial Application.

Partial Application

I’m still learning all these functional programming techniques. However, my understanding is that partial application is a technique within functional programming that postpones the need to accept a complete set of arguments for a given function. In other words, partial application is the act of deferring the acceptance of a complete set of arguments for a given function in which there is an expectation that the end-client will provide the rest of the arguments later. At least, that’s my understanding.

We can now take a function like:

let updateCells (grid:Map<(int * int), Cell>) =
 
    grid |> Map.toSeq
         |> Seq.map snd
         |> Seq.fold (fun grid c -> grid |> setReaction (c.X, c.Y)) grid

And refactor it to something like:

let updateCells (grid:Map<(int * int), Cell>) =
 
    grid |> getCells
         |> Seq.fold (fun grid c -> grid |> setReaction (c.X, c.Y)) grid

Conclusion

In conclusion, I recently returned to my Game of Life implementation after taking two weeks off. Upon returning, I observed certain pieces of code that jumped out at me. Specifically, I observed some minor duplication of function calls. I then implemented Function Composition and Partial Application to reduce duplication.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: