I have this sample function signature:
let func1 (input:'a when 'a :> (IReadOnlyDictionary<string, string>)) =
...
I would also like to permit 'a to be an IDictionary<string, string>). So either type could be passed. The code that uses the input parameter calls TryGetValue which both interfaces support.
Is it possible to specify an OR type constraint like this? If so, what is the specific syntax to do so?
I'm pretty sure you can't, but you can use SRTP to require the TryGetValue method:
let inline func1 (input : 'a when 'a : (member TryGetValue : string * byref<string> -> bool)) =
let mutable value = ""
let flag = input.TryGetValue("key", &value)
flag, value
It's ugly, but it works. Here it's called with an IDictionary:
dict [ "key", "value" ]
|> func1
|> printfn "%A" // (true, "value")
And here it's called in an IReadOnlyDictionary:
dict [ "key", "value" ]
|> System.Collections.ObjectModel.ReadOnlyDictionary
:> System.Collections.Generic.IReadOnlyDictionary<_, _>
|> func1
|> printfn "%A" // (true, "value")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With