Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can an F# generic type constraint specify more than 1 valid type?

Tags:

generics

f#

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?

like image 983
Matthew MacFarland Avatar asked Oct 28 '25 02:10

Matthew MacFarland


1 Answers

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")
like image 96
Brian Berns Avatar answered Oct 30 '25 11:10

Brian Berns



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!