Weird None behaviour in type providers

f#, type-providers

Solution

We have been bitten by this several times, so we create a specific note on this:

FsUnit uses type test to implement its DSL. Type inference doesn't work on this DSL, so make sure that two compared values belong to the same type.

For example, for some generic values such as `True`, `False`, etc, you need to specify their types (as `formula<fol>.True`, `formula<fol>.False`, etc) otherwise these values will be compared as being of type `obj`.

If you take a look at how FsUnit is implemented, it isn't really type-safe. I believe Jack P.'s pull request is a step towards making FsUnit more type-safe. It seems to be an area to improve FsUnit.

Problem

have a type provider with three properties 'a', 'b', and 'c' of type 'string', 'string option' and 'int option', respectively. When I have an instance with "", None, and Some 1 in those properties, this fails: ``` (row1.a, row1.b, row1.c) |> should equal ("", None, Some 1) ``` But all of these work fine: ``` row1.a |> should equal "" row1.b |> should equal None row1.c |> should equal (Some 1) ("", None, Some 1) |> should equal ("", None, Some 1) ``` How is this possible? What can make the None in b be different from any other None? After compilation, None is just a null, can two null values be different in .Net? Tuples have structural equality, like most F# types, so it should work. I get an NUnit.Framework.AssertionException with Message: ``` Expected: <(, , Some(1))> But was: <(, , Some(1))> ``` NUnit just calls .Equals, so that's where the problem is. This also fails: ``` (row1.a, row1.b, row1.c).Equals(("", None, Some 1)) |> should equal true ``` The runtime type of `row1` is `System.Tuple<string,Microsoft.FSharp.Core.FSharpOption<string>,Microsoft.FSharp.Core.FSharpOption<int>>`, so even this should work in theory: ``` row1 |> should equal ("", None, Some 1) ``` And in fact it does when there's no `None` in the tuple. I can't reproduce this behaviour with anything else but type providers.

Original source