Let's look at the differences between the two approaches:
In the first case, you are creating a list:
[ TypeB (), true; TypeB (), false ]
This has type (TypeB * bool) list
.
The dict function has type seq<'Key * 'Value> -> IDictionary<'Key,'Value> (requires equality)
.
Consequently, applying the dict
function
dict [ TypeB (), true; TypeB (), false ]
results in a value of type IDictionary<TypeB, bool>
.
IDictionary<TypeB, bool>
is not equivalent to IDictionary<TypeA, bool>
, these are completely different and incompatible types, hence the compiler error.
If you wanted to initialise your dictionary from a collection of more derived types in this way, you'd have to do the upcast explicitly, e.g.:
let iDict =
[ TypeB (), true; TypeB (), false ]
|> List.map (fun (a,b) -> (a :> TypeA), b)
|> dict
In your second example, this problem never materialised because you originally created a Dictionary<TypeA, bool>
.
You then use the Add
method to add something of TypeB
to the dictionary. Since Add
is a method, F# can perform automatic upcasting on the argument, such that your value of TypeB
is upcast to TypeA
automatically.