I ended the last post by proposing a syntax for asserting against floating point results:

```
let ``Comparing floating point numbers``() =
Given 1.0 |>
When ``dividing by 3`` |>
Then it should be (0.333333333 +/- 0.00000001)
```

How can we implement this? Let’s start with the trivial part: the `be`

function. It is just another “filler” word like `it`

and `should`

:

` let be f = f`

That leaves `(0.333333333 +/- 0.00000001)`

to perform the same role as the ```return```

function implemented previously i.e. it is a custom overloaded operator that should have a signature `'a -> TestContext<'a> -> unit`

. If we restrict `'a`

to be a `float`

, we could implement it as:

let (+/-) (expected: float) (tolerance: float) (context: TestContext) = Assert.AreEqual(expected, context.ToState, tolerance)

Then, assuming we have also defined `let ``dividing by 3`` = n / 3.0`

, the above test passes. However, we will want to comparing other types of floating point numbers, not just floats. Unfortunately we can’t just do this:

let (+/-) expected tolerance (context: TestContext<_>) = Assert.AreEqual(expected, context.ToState, tolerance)

The compiler can’t determine which overload of `AreEqual`

to use. Instead, we need to somehow write generic code that is constrained to work with any numeric type. This answer on StackOverflow shows how to use inline functions, explicit member constraints and statically resolved type parameters to (messily) achieve the required result:

```
let inline (+/-) (expected) (tolerance) (context: TestContext<_>) =
let zero = LanguagePrimitives.GenericZero
let actual = context.ToState
let absDiff = if expected > actual then
expected - actual
else
actual - expected
let absTolerance = if tolerance < zero then
-tolerance
else
tolerance
if absDiff < absTolerance then
()
else
let msg = sprintf "Expected: %s +/- %s\nBut was: %s" <| expected.ToString() <| tolerance.ToString() <| actual.ToString()
raise <| AssertionException(msg)
```

We basically have to implement `Assert.AreEqual(expected, actual, tolerance)`

ourselves, and I’ve chosen to throw the same exception that NUnit would throw so that it can be a drop-in replacement.

If we then implement ```dividing by 3```

in a similar generic manner:

```
let inline ``dividing by 3`` (n:^a) : ^a =
let three:^a = (Seq.init 3 (fun _ -> LanguagePrimitives.GenericOne)) |> Seq.sum
n / three
```

Then both of the tests below pass:

```
[<Test>]
let ``Comparing floats``() =
Given 1.0 |>
When ``dividing by 3`` |>
Then it should be (0.333333333 +/- 0.00000001)
[<Test>]
let ``Comparing decimals``() =
Given 1.0m |>
When ``dividing by 3`` |>
Then it should be (0.333333333m +/- 0.00000001m)
```

This brings me to the end of this series of posts. Hopefully I’ve illustrated one of the ways in which F# makes it (relatively) easy to write an internal DSL, as well as whetting your appetite for exploring the possibilities of low-ceremony BDD in F#.

Pingback: F# Weekly #14, 2013 | Sergey Tihon's Blog