a pitfall in argument and interface inheritance in fsharp

306 views Asked by At

Is there any real reason why KO would not work ?

  type IBase = 
      abstract member test : (unit * unit) -> unit

  type OK() = 
      interface IBase with

        member x.test ((titi,tata)) = () //OK

  type KO() = 
      interface IBase with

        member x.test (titi,tata) = () //fail : This override takes a different number of arguments to the corresponding abstract member    
2

There are 2 answers

4
Mark Seemann On BEST ANSWER

Because the parentheses mean something in F# (it indicates a tuple), so they're not the same.

As given, the test method is defined as a method that takes a tuple of two unit values as arguments. If you use Reflection to get the MethodInfo, the method is defined as:

Void test(System.Tuple`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit])

That matches the OK method, but not the KO method.

If you redefine the interface to

type IBase = 
    abstract member test : unit * unit -> unit

Then OK doesn't compile, but KO does.

This alternative version produces a test method which takes two arguments:

Void test(Microsoft.FSharp.Core.Unit, Microsoft.FSharp.Core.Unit)
0
Matthew Mcveigh On
abstract member test : (unit * unit) -> unit

Parentheses can be used to group complex parameters, such as when a function type is a parameter, or to indicate when a tuple is treated as a single parameter rather than as two parameters. http://msdn.microsoft.com/en-us/library/dd483468.aspx

Because of the parentheses your abstract method expects a parameter which is a tuple of 2 units, rather than 2 unit parameters

You can define the abstract method as:

abstract member test : unit * unit -> unit