Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Addressing interface conflicts in F#

I would like to implement the solution described here in F#: Inheritance from multiple interfaces with the same method name

Specifically, in F#, how do I address implementing interface functions that share the same name between two interfaces?

Here is the C# solution:

public interface ITest {
    void Test();
}
public interface ITest2 {
    void Test();
}
public class Dual : ITest, ITest2
{
    void ITest.Test() {
        Console.WriteLine("ITest.Test");
    }
    void ITest2.Test() {
        Console.WriteLine("ITest2.Test");
    }
}
like image 418
Robert Sim Avatar asked Jul 13 '17 21:07

Robert Sim


1 Answers

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.

like image 118
TheQuickBrownFox Avatar answered Sep 24 '22 01:09

TheQuickBrownFox