Category Archives: F#

Improving an Old Pattern

I wrote a blog post called Some(“F#”) is better than None back in 2015. I’ve grown quite a bit as a developer since then. Growth is what we strive for in this industry. Looking back over the blog post, I would like to improve upon the code to make it more expressive and bug free. The code I am focused on is comparing assembly versions to indicate whether an update would be required. The original code looked similar to this:

let checkForUpdate (rMaj, rMin, rBld) userVer =
    match (uMaj, uMin, uBld) with
    | (x, _, _)       when x < rMaj -> "Major"
    | (rMaj, x, _)    when x < rMin -> "Minor"
    | (rMaj, rMin, x) when x < rBld -> "Build"
    | _                             -> "None” 

My first instinct of change would be to return a Discriminated Union instead of a string. Using a discriminated union would give me type safety as well as better pattern matching later on in in other functions. I would define the discriminated union as:

type UpdateType =
    | Major
    | Minor
    | Build
    | NoUpdate

The checkForUpdate function would then look like:

let checkForUpdate (rMaj, rMin, rBld) userVer =
    match (uMaj, uMin, uBld) with
    | (x, _, _)       when x < rMaj -> Major
    | (rMaj, x, _)    when x < rMin -> Minor
    | (rMaj, rMin, x) when x < rBld -> Build
    | _                             -> NoUpdate 

This is a minor change with big benefits. Other functions handling the result can now pattern match on the type safe discriminated union instead of the infinite variations of potential string values.

Expanding the guards

I decided to add some tests for the function. I used FsCheck (a property based testing library) to battle test the function. This turned out to be a useful exercise as an issue was identified. The patterns were not handling the case correctly for a user who has an alpha or beta version which is considered a higher version than the current release.

To resolve the issue I ended up having to expand the guard clauses. I made the mistake of shadowing the release version labels rMaj and rMin. I had thought they would match the value contained in the labels, similar to an erlang pattern match. I was wrong. Shadowing a label means the system creates a new label of the same name within the current/nested scope.

let checkForUpdate (rMaj, rMin, rBld) userVer = 
    match userVer with
    | (uMaj, _, _) 
        when rMaj > uMaj                                     
            -> Major
    | (uMaj, uMin, _) 
        when rMaj = uMaj && rMin > uMin                   
            -> Minor
    | (uMaj, uMin, uBld) 
        when rMaj = uMaj && rMin = uMin && rMin > uBld 
            -> Build
    | _     -> NoUpdate

After the guard expansions all my tests passed. Although it works, this pattern match isn’t as expressive as we may like. Going forward, we should look into using Active Patterns.

Summary

There are some things to be aware of when using pattern matching. We can’t compare bound values directly in the pattern, we have to use a guard clause to compare them. Attempting to match bound values in the pattern will not match and will create a shadowed value. Use discriminated unions (DU) when given the choice for patterns. DUs improve the type safety of our functions and limit the number of variations our functions have to account for. Passing strings into functions have an infinite number of variations and for the most part be avoided. Sometimes making some small changes can make for more robust functions.

Asynchronous Child

Looking back at Running with Async we saw that you can run asynchronous workflows in multiple ways. We can use Async.RunSynchronously when we require the return value. We also looked at Async.Start when we don’t need a result. We also saw an example of running multiple asynchronous workflows using Async.Parallel. Let’s take a moment and get introduced to another means of starting asynchronous workflows.

Starting Children

We can use Async.StartChild when we want to evaluate an asynchronous workflow and get the result at a later time. This can be useful when aggregating data from multiple sources. Imagine having to hit multiple web servers or database servers to pull in data for analysis. We can start the workflows as children and get their results individually.

let getUrlContentSizeAsync (url : string) = 
    async {
        let request   = WebRequest.Create (url)
        use! response = request.AsyncGetResponse ()
        use stream    = response.GetResponseStream ()
        use reader    = new StreamReader(stream)
        let content   = reader.ReadToEnd() 
        do! Async.Sleep 500
        return (url,content.Length)
    }

let run1 = async {
        let! child = getUrlContentSizeAsync "http://techandwings.ca" 
                     |> Async.StartChild
        return! child
    }

run1 |> Async.RunSynchronously

In the function run1 we are using Async.StartChild to start the retrieving the content size for the URL. We are immediately returning the result from the child by using return!. Let’s add another URL.

let run2 = async {
        let! child1 = getUrlContentSizeAsync "http://techandwings.ca" 
                      |> Async.StartChild
        let! result1 = child1

        let! child2 = getUrlContentSizeAsync "http://nhl.com" 
                      |> Async.StartChild        
        let! result2 = child2

        return (result1, result2)
    }

run2 |> Async.RunSynchronously

When we start the run2 workflow we now receive a tuple containing the results of the two URLs we are retrieving. We start child1, wait for child1 to finish, start the child, and wait for its results. We’ve created our asynchronous workflow to retrieve the URL sizes sequentially. This is not an ideal use of the workflows. Let’s see if we can improve this by making a minor change.

let run3 = async {
        let! child1 = getUrlContentSizeAsync "http://techandwings.ca" 
                      |> Async.StartChild

        let! child2 = getUrlContentSizeAsync "http://nhl.com" 
                      |> Async.StartChild

        let! result1 = child1        
        let! result2 = child2

        return (result1, result2)
    }

run3 |> Async.RunSynchronously

Looking at run3 we can see we are starting the asynchronous workflows for both URLs before waiting for either result. The retrieval of the URLs’ sizes will happen concurrently. We then wait for the results of the child workflows and return them. This is a more effective use of Async.StartChild as we are now doing execution concurrently which can produce performance benefits when waiting for multiple long running IO operations.

If we enable #time in the REPL we should see a noticeable difference between run2 and run3. The difference is compounded by the Async.Sleep inserted in the getUrlContentSizeAsync function. You should see at least a half second speed up from run3 compared to run2.

Summary

Async.StartChild gives us the ability to control when start the asynchronous workflow and when we want the result. This in turn allows us to execute controlled asynchronous workflows concurrently. Executing asynchronous workflows as children is ideal for aggregating data from multiple sources.

Running with Async

Creating an asynchronous workflow doesn’t execute it immediately. It’s up to us to determine when and how we want the workflow to execute. So far we’ve been using Async.RunSynchronously to run our asynchronous workflow. By doing so, we are saying execute the async and wait for the result. This may not always be what we need. What if we want to write to a log file without blocking the current execution? We could use Async.Start.

Let’s revisit some code we looked at earlier. (Asyncing the F# Way)

let waiting () =
    async {
        printfn "Good night"
        do! Async.Sleep 2000
        printfn "Good morning"
    } |> Async.RunSynchronously
    printfn "Hello"

We get the expected results of:

Good night
Good morning
Hello

If we make a small change…

let nowaiting () =
    async {
        printfn "Good night"
        do! Async.Sleep 2000
        printfn "Good morning"
    } |> Async.Start
    printfn "Hello"

We’ve change the Async.RunSynchronously to Async.Start and our results are much different. We end up with results like this:

Hello
Good night
Good morning

(You’re results may be slightly different, however the “Hello” should always come before “Good morning”)

The reason Hello should always come before Good morning is we are no longer waiting for the result of the asynchronous expression. We are starting the asynchronous code and continuing on with the next expression.

Async.Parallel

We can use Async.Parallel when we have multiple asynchronous objects. This in turn can give some performance gains as multiple tasks are executed concurrently. We’ll use the getUrlContentsizeAsync and query some websites and sort them by size in descending order.

open System.IO
open System.Net

let getUrlContentSizeAsync (url : string) = 
    async {
        let request   = WebRequest.Create (url)
        use! response = request.AsyncGetResponse ()
        use stream    = response.GetResponseStream ()
        use reader    = new StreamReader(stream)
        let contents  = reader.ReadToEnd ()
        return (url,contents.Length)
    }

let sites = ["http://techandwings.ca"; 
             "http://www.cnn.com"; 
             "http://www.foxnews.com";
             "http://msnbc.com";
             "http://google.ca";
             "http://nhl.com";
             "http://mlb.com";
             "http://nfl.com"]

let asyncSites = sites |> List.map getUrlContentSizeAsync

In the REPL you can turn on some statistics analysis by entering the command:

#time;;

Let’s start by executing the list of asyncSites sequentially.

asyncSites |> List.map Async.RunSynchronously |> Seq.sortByDescending snd

The average results of running them sequentially a few times turned out to be around 4 seconds. (Your results may vary)

Real: 00:00:03.720, CPU: 00:00:00.869, GC gen0: 1, gen1: 0
val it : seq =
  seq
    [("http://nhl.com", 537569); ("http://mlb.com", 491099);
     ("http://nfl.com", 196920); ("http://www.cnn.com", 135159); ...]

If we make a couple of changes to the execution we should be able to speed it up. Let’s add Async.Parallel in exchange for the list map.

asyncSites |> Async.Parallel |> Async.RunSynchronously |> Seq.sortByDescending snd

The results of our new execution:

Real: 00:00:01.845, CPU: 00:00:00.820, GC gen0: 1, gen1: 0
val it : seq =
  seq
    [("http://nhl.com", 536551); ("http://mlb.com", 491099);
     ("http://nfl.com", 196920); ("http://www.cnn.com", 135159); ...]

My average results for running with Async.Parallel was just under 2 seconds. We’ve improved the performance of our experiment with a very minor change in how we are executing the asynchronous objects.

Summary

We’ve seen some new ways to run our asynchronous workflows. We have Async.RunSynchronous when we want to wait for the result. We can also start an asynchronous workflow without waiting for anything by using Async.Start. We’ve looked at the ability to chain multiple workflows into a list and execute them either sequentially or in parallel with the help of Async.Parallel. Running multiple asynchronous workflows in parallel can have some very drastic performance improvements. It’s always recommended to test and analyze any kind of enhancements to be sure. A very simple starting point for analysis is using the #time directive. Enabling #time will display some basic statistics about the code we are executing in the REPL.

Asyncing the F# Way

I recently gave a talk at the Winnipeg .Net User Group. This talk was focused on features of F# that are going to make their way into the world of C#. During the presentation I was talking about using local functions to wrap async functions. It was at this point someone asked if F# can do async/await. Well, the answer is yes.

The Async Builder

F# uses an Async Computation Expression for creating asynchronous workflows. The notation we use to denote an async computation is the async { ... }. Anything inside the curly braces are executed within the computation expression.

async {
    printfn "Good night"
    do! Async.Sleep 2000
    printfn "Good morning"
} |> Async.RunSynchronously

Looking at the example above, we have our async { ... } and our code within the curly braces. If you run the code in your REPL (Read Evaluate Print Loop) it will print “Good night”, wait 2 seconds, then print “Good morning”.

The Bang notation

The do! (do-bang) is our way of expressing we are evaluating an asynchronous expression. The do itself indicates we don’t care about the result. It’s the ! (bang) that the AsyncBuilder uses to unwrap the asynchronous expression’s result. It’s syntactic sugar to ensure our code is expressive and readable.

We use let! (let-bang) when we want to use the result of an asynchronous expression. In the doWorkAsync example below, we use the let! to bind the result of addAsync to the label result so we can print it.

let addAsync x y = async { return x + y }

let doWorkAsync = async {
    let! result = addAsync 4 6
    printfn "Result: %d" result
    }

Async.RunSynchronously doWorkAsync

Binding IDisposable

When we have an asynchronous expression which returns an object implementing IDisposable we should bind the result with use!. This unwraps the asynchronous expression, binds the disposable object, and disposes of the object when it falls out of scope. An example of use! is when retrieving the contents asynchronously from a website.

open System.IO
open System.Net

let getUrlContentSizeAsync (url : string) = 
    async {
        let request   = WebRequest.Create (url)
        use! response = request.AsyncGetResponse ()
        use stream    = response.GetResponseStream ()
        use reader    = new StreamReader(stream)
        let contents  = reader.ReadToEnd ()
        return (url,contents.Length)
    }

getUrl "http://techandwings.ca" |> Async.RunSynchronously

In the code above we are using the use! to unwrap the IDisposable response object. This in turn performs an automatic clean up when the object is no longer required.

Summary

We write asynchronous code in F# using the AsyncBuilder. The builder itself is syntactic sugar allowing us to write clean and expressive code. We use the Bang notation to unwrap the asynchronous calls within the builder. There are do!, let!, and use! to handle the results of an asynchronous expression. We’ve currently only looked at running the asynchronous code one way using the Async.RunSynchronously. We’ll look at more ways of running our code in a future post.

Deconstructing Records

Deconstruction let us focus on the values we want to match in our patterns. We’ve shown we can deconstruct tuples, but what about records? Absolutely.

A record is a data structure with named values. Records are immutable by default. We use records in exchange of tuples. Records give better context to what data is being represented. We’ll use the Astronaut record defined below as our data representation.

type Astronaut = { Name : string; Year : int }

Suppose we want to print an appropriate message based on the astronaut’s name. We’ll do a simple greeting for all astronauts except for “Dave” and “Neil”. We can create our function with a pattern match as below.

let greeting astronaut = 
    match astronaut with
    | {Name = "Dave"} -> "I'm sorry Dave, I'm afraid I can't do that."
    | {Name = "Neil"} -> "The first person to set foot on the moon."
    | {Name = name}   -> sprintf "Hello %s." name

If you look at the patterns in the match you will note we are deconstructing the Name value from the astronaut argument. Someone reading the code can easily see we are interested in the astronaut’s name.

We could be even more specific with matching on our Astronauts by using patterns below:

let greeting astronaut = 
    match astronaut with 
    | {Name = "Dave"; Year = 2001 } 
         -> "I'm sorry Dave, I'm afraid I can't do that."
    | {Name = "Neil"}               
         -> "The first person to set foot on the moon."
    | {Name = name}                 
         -> sprintf "Hello %s." name

We’ve gone further in isolating the values we want for our patterns. The more values you add the more specific your patterns become. In the example above we have a case using the Name and Year deconstructed from the astronaut to get Hal’s response to Dave. All other astronauts named Dave will get the standard greeting.

Deconstruct OR what…

Let’s go back to matching on name only. What if our name isn’t proper case? What if Dave is actually a “dave” or “DAVE”? We may still want to match on those “Dave”s. Here is where some of the power of F#’s pattern matching starts to shine. We can write our pattern to include those other “Dave”s by combining deconstruction and the OR Pattern.

let greeting astronaut = 
    match astronaut with
    | {Name = "Dave" | "dave" | "DAVE"} 
        -> "I'm sorry Dave, I'm afraid I can't do that."
    | {Name = "Neil"} 
        -> "The first person to set foot on the moon."
    | {Name = name}   
        -> sprintf "Hello %s." name

We’ve certainly improved our pattern to include more cases of “Dave”. We can take our pattern one step further and make our patterns case insensitive. The first way will be more familiar for OOP developers. We can use the property accessor to get the Name to then lower and use the property again to print the name. The other way would be to use a pattern match in the function signature. We can do pattern matching and deconstructing in the function arguments.

let greeting astronaut = 
    match astronaut.Name.ToLower() with
    | "dave" 
        -> "I'm sorry Dave, I'm afraid I can't do that." 
    | "neil" 
        -> "The first person to set foot on the moon."
    | _      
        -> sprintf "Hello %s." astronaut.Name


let greeting' {Name=name} = 
    match name.ToLower() with
    | "dave" 
        -> "I'm sorry Dave, I'm afraid I can't do that."
    | "neil" 
        -> "The first person to set foot on the moon."
    | _      
        -> sprintf "Hello %s." name

It’s not overly common to use deconstruction in the function signature. It can lead to some ambiguity in the code. We are focusing on the values we care about, however the function signature may no longer have the same readability it did before with the astronaut value.

Summary

We’ve covered the ability to deconstruct records in our patterns. We aren’t limited to one value for deconstruction. We can match on any number of values in a record, and the number of values can vary between patterns. F# is not limited to only deconstruct records in the match with construct. Matching can be used by the function construct and in the declaration of function arguments. We can also combine deconstruction with OR to reduce the number of patterns and improve readability. It’s the ability to combine patterns which let’s the power of F# shine its expressiveness.

Beyond Constant Pattern Matching

Pattern matching is a vital aspect of functional programming. It can make our code more expressive by eliminating noise. We’ll look into a few more patterns that give us the power and flexibility to create readable match expressions.

OR Pattern

The OR pattern is used to group multiple patterns which return the same result. This can be considered a short hand for multiple patterns. A simple match expression verifying a number is below 10 and prime can be written multiple ways.

// Return value for each number
let isPrimeBelow10 = match number with
                     | 2 -> true
                     | 3 -> true
                     | 5 -> true
                     | 7 -> true
                     | _ -> false

// Using the OR pattern
let isPrimeBelow10 = match number with
                     | 2 | 3 | 5 | 7 -> true
                     | _             -> false

The second version of isPrimeBelow10 is easier to reason about as it declares the patterns 2, 3, 5, and 7 are grouped to the same result. The noise of all the extra -> true has been removed. This gives the reader a visual cue about the relationships of the patterns as well as reduces duplicate code.

Guards

Guards are used to match on patterns that require more than a constant. We use the when keyword followed by an expression which evaluates to a boolean. If the guard expression evaluates to true then that pattern matches. Let’s say we want to classify a value as normal if it is within 100 to 200. That would take a lot of patterns if we used the OR pattern exclusively. It also doesn’t solve the situation if we wanted to indicate whether the value was high or low. We can use guards to accomplish our task.

let withinNormals number = match number with
                           | x when x > 200 -> High
                           | x when x < 100 -> Low
                           | _              -> Normal

We have three patterns with two of them using guards. The first pattern binds number to the label x and evaluates x > 200. If it evaluates to true, the match returns High. The second pattern does something similar, with the exception of evaluating x < 100. The final pattern is a wildcard which returns if the previous patterns are not matched.

Guards allow us to do more than just match on constants. We can expand our withinNormals to be more reusable.

let withinNormals (lowLimit, highLimit) number = 
    match number with
    | x when x > highLimit -> High
    | x when x < lowLimit  -> Low
    | _                    -> Normal

We have the same three patterns but this time we are using the arguments passed in determine the lower and upper limit. Guards let us do more than match on constant values, they give us the flexibility to create reusable patterns.

Deconstruct

Deconstruction allow the pattern to focus on what is being pattern matched. We left off Pattern Matching with Constants with a pattern matched version of Fizz Buzz. Here is the implementation again.

let printFizzBuzz number = match (number % 3, number % 5) with
                           | (0, 0) -> printfn "FizzBuzz"
                           | (0, _) -> printfn "Fizz"
                           | (_, 0) -> printfn "Buzz"
                           | _      -> printfn "%d" number

The printFizzBuzz function takes a number and creates a tuple of the results of number modulus 3 and 5. Our patterns deconstruct the tuple and match those results with constants.

We can even completely ignore values from deconstructed objects. Here we only care about the third value in the tuple. We are using the patterns to deconstruct the tuple while ignoring the first two values in the tuple. Our patterns are only focused on the values important to it.

match tupleOf3 with
| (_,_,0)            -> "0"
| (_,_,1)            -> "1"
| (_,_,x) when x < 0 -> "Negative"
| _                  -> "Larger than 1"  

Summary

The OR pattern can be used to group patterns together which have the same return value. Redundant code can be eliminated with the use of the OR pattern. Guards give match expressions the ability to compare values in patterns and not restrict us to constants. Deconstruction let patterns focus on what is being matched instead of dealing with the whole object.

Pattern Matching with Constants

Pattern matching is a staple of any functional programming language. F# has a decent pattern matching system with 16 matching patterns out of the box. You also have the ability to extend the pattern matches by using Active Patterns. Let’s start with some common pattern matches for F#.

The basic syntax for pattern matching in F# is a match with expression. The with is then followed by a vertical bar and a pattern.

match item_to_be_matched with
| pattern -> result

This is a single case pattern match. It’s not used much at all. Generally pattern matches have multiple cases. Each pattern is separated by a vertical bar. You can think of the vertical bar as being “OR”.

match item_to_be_matched with
| pattern1 -> result1
| pattern2 -> result2
.
.
.
| patternN -> resultN

Constant Pattern

Using a constant pattern is very similar to a switch statement in C#. Any type that can be defined as a constant can be used in this type of pattern.

match number with
| 0 -> "Zero"
| 1 -> "One"
| 2 -> "Two"
match role with
| "administrator" -> Administrators
| "manger"        -> Managers
| "user"          -> Users

Exhaustive vs Incomplete Patterns

A pattern match is considered exhaustive when it accounts for every possible pattern. We don’t always have to use exhaustive patterns, however we do run the risk of receiving an exception if no match is found. If you are using an editor like Visual Studio or Visual Studio Code (with Ionide-Fsharp) you will get highlighting indicating a pattern may not be accounting for every possibility. It’s preferable to use exhaustive patterns to eliminate the possibility of a match failure exception.

Visual Studio Code with Ionide-Fsharp indicating an incomplete pattern.
VSCode with Ionide-FSharp - Incomplete Match

Wildcard Pattern

The wildcard pattern is used as a catch all pattern. This is denoted by an underscore or a generic label in the pattern. Use of an underscore informs the next developer the value is of no importance. The wildcard pattern is very much like the default clause of a switch statement in C#. This will take any incomplete pattern and make it exhaustive. We can make the isZero function exhaustive by adding the wildcard pattern.

let isZero number = match number with
                    | 0 -> true
                    | _ -> false
let greeting name = match name with
                    | "hal" -> printfn "I'm afraid I can't do that Dave"
                    | _     -> printfn "Hello %s" name

You do have to be careful when using the wildcard. If a business requirement changes and you forget to add the new pattern, the wildcard will happily swallow the match thus leaving you with some unintended results.

Summary

Pattern matching with constants is very similar to the C# switch construct. This is where the similarities end until C# 7. As I mentioned at the beginning of this post, F# has 16 different patterns. We’ll be getting into more of those patterns in future posts. Here is a FizzBuzz implementation using the constant pattern match with Tuple deconstruction. Exciting things are on the way.

let printFizzBuzz number = match (number % 3, number % 5) with
                           | (0, 0) -> printfn "FizzBuzz"
                           | (0, _) -> printfn "Fizz"
                           | (_, 0) -> printfn "Buzz"
                           | _      -> printfn "%d" number

F# Prototyping with Visual Studio Code

I’ve been using Visual Studio Code (VSCode) for the majority of my F# development since December 2016. I have to admit it has become my prototyping tool of choice. Visual Studio Code is a nice lightweight IDE, if you can call it an IDE. It’s more of a text editor with a great set of extensions. VSCode loads very quickly which makes it excellent for testing out those single shot ideas. VSCode is a cross platform editor which contributes to its ease of use. You get relatively the same feel on Windows, Mac OSx, or linux. Visual Studio Code, with a few extensions, has become my main editor for prototyping in F#.

If you haven’t looked at VSCode before, you can get it at https://code.visualstudio.com/.

The very first thing I do after installing VSCode is getting the Ionide-fsharp extension. You can install the extension by going to View -> Extensions in the menu. In the extensions window, enter ionide-fsharp in the search box. The extension should show in the results window with an install button.

Ionide-Fsharp will give you access to F# Interactive (F#’s REPL) from within VSCode. You also get a wide range of benefits such as syntax highlighting, codelens for function types, hover tooltips, and more. When it comes to prototyping though, having immediate feedback of a REPL is the best tool one could have.

I add some custom keybindings in VSCode for interacting with the REPL. My preferred shortcuts are as follows:

  • Ctrl+i – Starts / restarts the REPL
  • Ctrl+’ – Sends the current line from the editor to the REPL for evaluation
  • Ctrl+; – Sends the selection of code from the editor to the REPL

You can modify the keybindings by going into (Mac) Code -> Preferences -> Keyboard Shortcuts or (Windows) File -> Preferences -> Keyboard Shortcuts and adding the code snippet below:

    { "key": "ctrl+;",                "command": "fsi.SendSelection",
                                     "when": "editorTextFocus" },
    { "key": "ctrl+'",                "command": "fsi.SendLine",
                                     "when": "editorTextFocus" },
    { "key": "ctrl+i",                "command": "fsi.Start",
                                     "when": "editorTextFocus" }

Visual Studio Code and Ionide-Fsharp have truly changed how I prototype ideas. I can load the editor, start the REPL, and begin testing my ideas in mere seconds. This makes VSCode enjoyable and efficient for F# prototyping.

Currying and Applying Arguments

I gave a talk called Some(‘F#’) is Better Than None at Winnipeg Code Camp on January 28, 2017. The talk was catered toward developers who have never looked at F# or those who never considered F# as being a useful prototyping tool.

During the talk I made a brief mention to currying and partial application. After the talk I received a great question along the lines of: if every function only takes one argument, how is it we are able to pass multiple arguments to a function?

Currying

Currying is the process of transforming a function which takes multiple arguments into a sequence of functions where each new function takes only one argument. If we were to write the function:

let addThreeNumbers x y z = x + y + z

This function looks like it takes three arguments, however the signature of addThreeNumbers is converted to int -> int -> int -> int. We can read the function signature as: addThreeNumbers has type of int goes to int goes to int goes to int. The last type in the signature denotes the return type of the function.

Applying arguments

Using the addThreeNumbers function we defined earlier, we can call the function as:

addThreeNumbers 1 2 3

Since we are passing in the full number of arguments the function evaluates immediately giving us the result of 6.

As we are passing in arguments, the function applies what it can with the arguments given. Each time we add an argument it peels off the leading type ->, eventually reaching the point where there is nothing left to apply which then evaluates the result.

// int -> int -> int -> int
let addThreeNumbers x y z = x + y + z

let result = addThreeNumbers 1 2 3
// can be thought of as
let result' = (((addThreeNumbers 1) 2) 3)

// You can also apply the arguments in steps and create 
// intermediate functions.

// addTwoNumbersWith1 :: int -> int -> int
let addTwoNumbersWith1 = addThreeNumbers 1

// addOneNumberWith1and2 :: int -> int
let addOneNumberWith1and2 = addTwoNumbersWith1 2

// six :: int
let six = addOneNumberWith1and2 3

Currying and partial application are very powerful features. Currying is the process of transforming a function which takes multiple arguments into a sequence of functions which take one parameter. Applying arguments to a curried function peels off a function from the sequence. This allows you to build reusable functions.

Advent of Code 2016: Things I’ve Learned

I’ve been engaged in the Advent of Code 2016. Attempting to improve upon my solutions from 2015. I have improved a lot since last year. However, as of Day 8 there are some things that I have notably learned. Well, some things I’ve forgotten and learned again. Here are the highlights so far:

Seq.chunkBySize

This was added in F# 4.0. This function allows you to partition your collection into arrays of a size of your choosing.
For example:

[1 .. 6] |> Seq.chunkBySize 2;;  // seq [[|1; 2|]; [|3; 4|]; [|5; 6|]]
[1 .. 6] |> Seq.chunkBySize 3;;  // seq [[|1; 2; 3|]; [|4; 5; 6|]]

There is a caveat, if the number of items in the collection is not equally divisible by the chunk size, the last array will have fewer items.

[1 .. 6] |> Seq.chunkBySize 5;;  // seq [[|1; 2; 3; 4; 5|]; [|6|]]

Slicing

This one I seem to forget is available. I always start with a for or a skip |> take and then I remember. It can make your code a lot easier to read.

Spoilers for day 8

I am using a mutable 2D array for day 8. There was a similar problem last year and I chose to go fully immutable and got destroyed by Garbage Collection. Mutability we go! The problem called for shifting pixels (which wrap) on a display. I decided to get the current row of pixels starting at origin (I define the origin as being the length of the array minus the amount we are shifting). I then could apply the shifted row to the mutable 2D array.

My initial implementation:

member this.RotateRow (y,shift) =
  let origin = width - shift
  seq { for i in {origin .. width - 1} do
          yield display.[i, y]
        for i in {0 .. origin - 1} do
          yield display.[i, y] } 
  |> applyShift

It’s not terribly bad. We get the items from shift origin to the end of the array followed by items from the start of the array to origin. We can do better with slicing.

Slicing an array or list is a matter of using the indexer after the label.

let l1 = [1 .. 100];;
l1.[6 .. 10];; // [7; 8; 9; 10; 11]
l1.[7 .. 11];; 
l1.[.. 10];;   // [1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11]
l1.[95 ..];;   // [96; 97; 98; 99; 100]

Did you notice I said indexer? Yes, slice takes the items via their position in the collection. This is something you will need to be aware of. If you want the first ten items using slice you would use [..9], as the tenth item is in position nine.

Updating my original solution using slices instead of for constructs has made my solution more concise and readable.

member this.RotateRow (y,shift) =
  let origin = width - shift
  seq { yield display.[origin .., y]
        yield display.[.. origin - 1, y] } 
  |> applyShift

By using slices I removed the need to calculate the end of the array. This eliminated the chance of an off by one error. <insert bad off by 2 joke here>

Seq.windowed

Seq.windowed is handy when you need to look for specific patterns in a collection. This function works by taking a collection and creating a sliding window of arrays with the length you specify.

Some examples of course:

let l1 = [1 .. 5];;
l1 |> Seq.windowed 2;; // seq [[|1; 2|]; [|2; 3|]; [|3; 4|]; [|4; 5|]
l1 |> Seq.windowed 3;; // seq [[|1; 2; 3|]; [|2; 3; 4|]; [|3; 4; 5|]
l1 |> Seq.windowed 4;; // seq [[|1; 2; 3; 4|]; [|2; 3; 4; 5|]]
l1 |> Seq.windowed 6;; // seq [] 

If you try to get windows larger than the size of the collection, you end up with an empty collection.

Seq.chunkBySize, slicing, and Seq.windowed are my three most notable take aways from the first 8 days of Advent of Code 2016.