I have defined an interface in F# with an overloaded method. As per compiler request, the overload uses tupled arguments instead of curried ones:
type IInterface =
abstract member Do : (int * string) -> unit
abstract member Do : int -> unit
I then create a class which implements the interface:
type ImplementingClass =
interface IInterface with
member this.Do (i, s) = ()
member this.Do i = ()
However, doing so yields the compiler error for the first of both methods: "This override takes a different number of arguments to the corresponding abstract member"
What am I doing wrong here?
There is a subtle difference between the following two:
abstract member Do : int * string -> unit
abstract member Do : (int * string) -> unit
If you add the parentheses, you're saying that the parameter is a tuple and the compiler should produce a method taking Tuple<int, string>
. Without parentheses, the method will be compiled as taking two parameters. Most of the time, this is hidden and you can ignore it - but sadly, not always.
So, you can either change your interface definition to use ordinary "two-parameter" method (this would be my preferred method - you can still call the method with tuple as an argument and looks nicer 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 it is:
type ImplementingClass =
interface IInterface with
member this.Do((i:int, s:string)) = ()
member this.Do(i:int) = ()
Sadly, this is a bit ugly - you need the type annotations so that the compiler can unambiguously decide which method you're implementing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With