You can't implement multiple instances of a generic interface in F#. This is a bummer in my case, because I had a plan to implement an interface called ICastableTo<'T> that could be used for pattern matching:
type ICastableTo<'T> =
/// <summary>
/// Returns a casted version of the object
/// </summary>
member this.Value : 'T
...
(*x:obj*)
match x with
| :? ICastableTo<SomeType> as x -> doSomethingWith(x.Value)
| _ -> invalidOp("can't cast like that")
However, when I tried to actually use this, I face an issue because I can't implement mulitple version of the ICastableTo interface (see Implementing the same interface at different generic instantiations), yet some of my classes are actually castable to more than one type.
What would be my best option here? I could of course define an ICastable interface and use a "PossibleCasts" property that would expose all available casting delegates but that's not super beautiful and does not play that well with inheritance.
Here's what my code looks like:
type BindableFunction<'T,'V>(func : 'T -> 'V) =
member val Parent : 'T = nothing with get, set
interface Specializable with
member SpecializeFor(x: obj) =
match x with | :? ICastable<'T> as x -> Parent <- x.Value | _ -> invalidOp("")
and then I've my castable classes. For example, I've a TCell class that has a reference to a Cell (composition) and can therefore be casted into a Cell for the purpose of function binding, even if there's no inheritance link between the two types.
I think what I will end up doing is generating the "match x with | ICastable<'T>" to be non-generic (aka, I'll use ICastableOf_Cell and find the good interface using Reflection (get type by name) and then generate the code using Reflection.Emit.
The other option would be to give the BindableFunction two generic types, one being the value type, and the other one ICastableOf_Cell, which is maybe a better idea but would make my code more verbose at various places.