I was somewhat surprised when I realised that F#’s map implements both IDictionary<‘Key, ‘Value> and ICollection<KeyValuePair<'a, 'b>> considering that both supports mutation (add and remove) as part of the contract.
Looking at the implementation of map it simply excepts when you try to cause mutation!
let map = [| (1, "one"); (2, "two") |] |> Map.ofArray
let dict = map :> IDictionary<int, string>
dict.Add(3, "three");;
the above code throws the exception:
System.NotSupportedException: Map values cannot be mutated. at
Microsoft.FSharp.Collections.FSharpMap2.System-Collections-Generic-IDictionary2-Add(TKey
k, TValue v) at .$FSI_0007.main@() Stopped
due to error
which is as expected.
For an immutable collection to be able to expose itself as a mutable one only for it to throw exception when the consumer of that collection tries to cause mutation seems such a dangerous decision.
Am I missing something here?
IsReadOnlyallows for the interface to be read-only even though it provides writable methods.