Intro

This actually happened months ago but, I’ve been wanting to discuss F# a bit.

As a way of “sharpening the saw”, I went through Chris Marinos’s excellent F# Koans and though I’d post my solution to one of the problems. I’ve been playing with functional programming for a long time and bounce between different languages and implementations. Historically I’ve preferred the simplicity of “Lisps” like Clojure over the terse nature of F# and ML but having lived in Javascript and felt the pain of a loosely typed world and with being a C# user I’ve decided to give F# another spin.


The Problem:

Below is a list containing comma separated data about

Microsoft’s stock prices during March of 2012. Without

modifying the list, programmatically find the day with the

greatest variance between the opening and closing price.

Full Problem Here

I’ve spent hundreds of hours my life writing code that parses CSVs and massaging data and as a developer and I’m not alone. So I saw this as a practical problem to solve.


The Solution


The Approach

My approach to solving was the following:

1.Define the “Shape” of the data [lines 1-8]

2.Populating the fields [line 13-21, 23]

3. Evaluating for the result by calculating the absolute value of the difference between opening and closing [line 25]


Breaking it down

The moment that made me fall in love with F# was how my solution looked. I could do it cleanly in 3 lines of core logic run. Looking at the body of YouGotTheAnswerCorrect.

Creating the rows from the data

How it works

Taking the conceptual understanding of map up a level.  You can think of map the same way you would think of a for each loop iterating over a collection with a couple of notable differences.

  1. Map transforms the data in each row based on whatever function you give it. (In this case its createRowFromCSV)
  2. Apply the map to stockData without the first row (note the “Tail”)
  3. Return all the transformed rows in the collection and store in the rows variable.

So in plain C# (without LINQ) you would do something like the following.

If you were using LINQ in C# Select performs the exact same functionality as the map function.


Getting the Diffs

“For the greatest variance get the absolute value of the difference between the opening and closing values.”

How it works

In this line, we are once again using the Seq.map function to apply a function to the given collection. The collection is the rows collection we just created on the previous line. For each item in the “rows” collection, we are creating a tuple containing the Date of Entry that we need to solve the problem and the absolute value of the difference.

The structure of each of the items in our diff collection will now look like this.

2012-03-30 0.140000000000001

Tuples

Tuples are some of our fundamental data structures in functional programming with F#. In the simplest terms, a tuple represents a group of values. The values in a tuple can be any combination of different types. They, like most of the variables in F#, are immutable. Here is a quick example.


Getting the Greatest Change

At this point, all that is left is to get the biggest number and return the date associated with it. We do that with the following line.

How it works

The function maxBy has similar arguments to that of the map function.The key difference is that in maxBy the function must perform a comparison of the elements in the function argument.

Looking back at maxBy, for each tuple, we are passing the second element (the absolute value of the change amount) and returning the first element in the tuple. (the date)

This gives us 2012-03-13 as the solution which matches our assertion in the Koan. YA!!!


I had so much fun with it that I joined and lurk the Functional Programming and F# slack Channels, became a member of the F Sharp Software Foundation and have been slowly trying to adapt my C# projects to F# in my spare time. Moral of the story… sometimes it takes a second look for things to click.  Also, the devs on the F# channels are generally very nice and easy going and FP can be difficult to wrap your head around. Its nice to have a group that does not mind your beginner questions.

The full solutions

Full F# Example Here

Full C# Example Here