In F#, interfaces are always implemented explicitly so this isn't even a problem that needs to be solved. This is how you would implement these interfaces whether or not the method names were the same:
type ITest =
abstract member Test : unit -> unit
type ITest2 =
abstract member Test : unit -> unit
type Dual() =
interface ITest with
member __.Test() = Console.WriteLine("ITest.Test")
interface ITest2 with
member __.Test() = Console.WriteLine("ITest2.Test")
This makes sense when you consider that access of interface methods in F# is also explicit. If you have a Dual
you can't call the the Test
method. You must first upcast to either ITest
or ITest2
:
let func (d:Dual) = d.Test() // Compile error!
let func (d:Dual) =
(d :> ITest).Test()
(d :> ITest2).Test()
// This is fine
Note that there is a safe upcast operator :>
for casting up the object hierarchy in a way that is guaranteed to work at compile time, and cannot result in a run-time exception.
Sometimes this explicit method access is inconvenient, but I believe it leads to a simplification of the type system that makes more type inference possible and increases convenience and safety overall.