Are there any ‘underlying’ differences between Map.TryFind , Map.tryfind and Map.TryGetValue?

Given this code:

let myMap = Map [ (1,"one") ; (2, "two") ; (3, "three") ]
let one = myMap.TryFind 1
let two = myMap |> Map.tryFind 2
let three = myMap.TryGetValue 3

…I get the following output:

val one: string option = Some "one"
val two: string option = Some "two"
val three: bool * string = (true, "three")

…and that’s all fine.

However, are there any advantages/disadvantages performance/style/other-wise in using one over the others?

Are any of them considered to be ‘old’ and/or ‘frowned upon’ in any way?

Is one of them much ‘better’ than the others for some non-obvious reason?

Should I normally be using one, and under which circumstances would the advice be different?

I would recommend prefering one of the tryFind variants over TryGetValue. TryGetValue comes from the IDictionary interface that Map implements, so it’s the more C# approach. Working with an option type is more idiomatic and safer than getting a bool + a string which could be null whenever the bool is false.

Between the two tryFind variants, it’s largely up to preference, and to some extent, context. The Map.tryFind function is going to work better with function composition (>>), with pipelines (|>), and with the type inference system without needing an annotation (like let fn xs = Map.tryFind "key" xs compiles but let fn xs = xs.TryFind "key" doesn’t unless you add an annotation).
The myMap.TryFind method is going to work better with “fluent” C# APIs (like myMap.TryFind("key").AddService(myService).Build()) and is less total code.

1 Like

Thanks for that.
I’d come to some similar conclusions but thought I’d ask in case there were details which I hadn’t taken into account.

1 Like