A week or two ago, Fresh Brewed Coder Bryan Hunter posted a video to explain how to debug Erlang apps. In the tutorial, he stepped through a recursive function to display the various concepts. I thought it would be interesting to take that simple example and explore a few ways to write it in F#.
Let’s start by reviewing Bryan’s example (which calculates the average of a provided list of number). Here’s what his average.erl source file looks like:
-module(average). -export([calculate/1]). calculate(X) -> calculate(X,0,0). calculate([H|T], Length, Sum) -> calculate(T, Length+1, Sum+H); calculate(, Length, Sum) -> Sum/Length.
Porting the Code to F#:
So how would you write this in F#? As with any language, there are several options. A fairly straight forward port might look like this:
let calculate x = let rec calc list length sum = match list with | head :: tail -> calc tail (length+1) (sum+head) |  -> sum/length calc x 0 0 printfn "Value is %O" (calculate [10;22])
Breaking it Down:
The above code defines the calculate function that takes a list of integers as a single argument.
Next, a recursive function (the “rec” keyword indicates that it is recursive) named calc is defined (line 2). This function takes a list of integers as the first argument, the current length as the second argument, and the current sum as the last argument.
At the heart of this recursive function is a pattern match against the provided list (line 3). Using something known as the cons pattern, the first pattern (line 4) attempts to decompose the provided list into a “head” (the first element in the list) and “tail” (the rest of the elements).
If the first pattern is a match, the calc function is called with the “tail” list as the first argument, the length value incremented by 1 as the second argument, and the result of the sum value combined with the first value from the list (i.e. the head) as the third argument. This continues until the list is empty, at which point the cons pattern no longer results in a match and the second pattern is evaluated.
By the time the second pattern (line 5) is evaluated, the match will succeed due to the list now being empty. This causes the average to be calculated (i.e. sum/length) and returned.
Line 6 kicks off the initial call to the calc recursive function with the initial list as the first argument and default length and sum values of 0.
Finally, the last line (line 7) kicks off the whole thing with the call to calculate the average of the numbers 10 and 22 (as used in Bryan’s demo).
While the approach above is pretty compact, F# provides a library that contains a high-order function that makes this even easier. The following line of code will also calculate the average of the values in a list of integers:
[10;22] |> List.averageBy (fun number -> float number)
This version includes the following improvements:
- Libraries for frameworks 3.5 and 4.0.
- Support for NUnit version 184.108.40.20692.
- Several new functions including:
greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo, shouldFail, endWith, startWith, and ofExactType.
Examples of the functions mentioned above are shown below:
module FsUnit.``Given a bunch of random tests`` open NUnit.Framework open FsUnit [<Test>] let ``When 11 it should be greater than 10``() = 11 |> should be (greaterThan 10) [<Test>] let ``When 11 it should be greater than or equal to 10``() = 11 |> should be (greaterThanOrEqualTo 10) [<Test>] let ``When 10 it should be less than 11``() = 10 |> should be (lessThan 11) [<Test>] let ``When 10 it should be less than or equal to 11``() = 10 |> should be (lessThanOrEqualTo 11) [<Test>] let ``When an empty List it should fail to contain item``() = shouldFail (fun () ->  |> should contain 1) [<Test>] let ``When fsharp it should end with rp``() = "fsharp" |> should endWith "rp" [<Test>] let ``When fsharp it should start with fs``() = "fsharp" |> should startWith "fs" [<Test>] let ``When 1 it should be of exact type int``() = 1 |> should be ofExactType<int>
An example of what this looks like when run in Resharper’s Test Runner is shown below:
A Side Note: If you haven’t written many tests in F#, the lack of spaces in the test names may surprise you. This is a feature of F# that allows almost any sequence of characters to be enclosed in double-backtick characters (i.e. “) and consequently treated as an identifier.
I hope you enjoy the latest enhancements to FsUnit. You can find the full source at http://fsunit.codeplex.com/.
There is a new project template available on Visual Studio Gallery for creating ASP.NET MVC 4 solutions with F# and C#. The current release of this project template allows creation of an empty ASP.NET MVC 4 web application (either ASPX or Razor), a F# project for controllers/models/etc., and an optional F# project that can be used to contain unit tests. The project creation wizard dialog box is shown below:
In the future, this template will be extended to include at least one additional project type.
To get the template, do the following (Note: Visual Studio 2010/11 Professional (or above) is required to use this template.):
1. In Visual Studio, navigate to File | New and select Online Templates.
2. Search for “fsharp mvc” and select the F# C# MVC 4 project template (see below):
The solution that was used to build this template can be found at https://github.com/dmohl/FsCsMvc4Template.
I’ve talked about testing CoffeeScript with Pavlov in a previous post. Today, I’m going to talk about a couple of ways to quickly get started with Pavlov–a BDD API that sits on top of QUnit–in an ASP.NET web app.
In the past, whenever I wanted to start creating Pavlov specs, I would go out to the Pavlov GitHub site, grab the appropriate files, and add them to my web app. While this process isn’t all that time consuming, there is now a better way. Now I can simply install the Pavlov NuGet package using the NuGet Visual Studio Extension. This package adds a folder named Specs under the Scripts folder that includes a barebones html file and pavlov.js.
An example of what the file structure looks like after this package is installed is shown below:
If I prefer to have a simple example to start with, I can alternatively install the Pavlov.Sample package. This adds the same files as the Pavlov package, but also includes an example.specs.js file with the code from the example on the Pavlov GitHub site.
Lastly, I’ve been writing a fair amount of CoffeeScript lately, so I may prefer to have the sample specs written in CoffeeScript. All that is needed for this is to make sure that Mindscape Web WorkBench Visual Studio Extension is installed (this is a onetime install) and then install the Pavlov.Coffee NuGet package. The files are then added to the project including a example.specs.coffee file that looks like this:
pavlov.specify "Pavlov Example", -> describe "A feature that is being described", -> foo = undefined before -> foo = "bar" after -> foo = "baz" it "can be specified like so", -> assert(foo).equals('bar')