F #: implementation of an interface with overloaded elements

I defined an interface in F # with an overloaded method. As requested by the compiler, overloading uses alternating arguments instead of curried:

type IInterface = abstract member Do : (int * string) -> unit abstract member Do : int -> unit 

Then I create a class that implements the interface:

 type ImplementingClass = interface IInterface with member this.Do (i, s) = () member this.Do i = () 

However, this results in a compiler error for the first of both methods: "This override takes a different number of arguments for the corresponding abstract element"

What am I doing wrong here?

+5
source share
1 answer

There is a subtle difference between the following two:

 abstract member Do : int * string -> unit abstract member Do : (int * string) -> unit 

If you add parentheses, you say that this parameter is a tuple, and the compiler should create a method that accepts Tuple<int, string> . Without parentheses, the method will be compiled as taking two parameters. In most cases, this is hidden, and you can ignore it, but, unfortunately, not always.

So, you can either change the interface definition to use the usual β€œtwo-parameter” method (this would be my preferred method - you can still call the method with a tuple as an argument and look better in the .NET / C # view):

 type IInterface = abstract member Do : int * string -> unit abstract member Do : int -> unit type ImplementingClass = interface IInterface with member this.Do (i, s) = () member this.Do i = () 

Or you can implement the interface as is:

 type ImplementingClass = interface IInterface with member this.Do((i:int, s:string)) = () member this.Do(i:int) = () 

Unfortunately, this is a little ugly - you need type annotations so that the compiler can uniquely decide which method you are implementing.

+9
source

All Articles