jon hanson
jon hanson

Reputation: 9408

Default method with tupled parameters for an F# class

Why does this F# class not compile(with VS2010):

type Base =
    abstract func : (int * int) -> int

    default this.func (x : int, y : int) : int =
        x + y

The default implementation of func causes this compilation error:

Error   9   This override takes a different number of arguments to the corresponding abstract member

If I change it be a member:

type Base =
    abstract func : (int * int) -> int

    member this.func (x : int, y : int) : int =
        x + y

Then it compiles (though I believe now the abstract func lacks an implementation), and the type of the 2nd func matches the 1st.

On a related note, why doesn't the compiler require the 2nd definition of Base to have an AbstractClass attribute?

Upvotes: 2

Views: 262

Answers (2)

Daniel
Daniel

Reputation: 47904

Just get rid of the parentheses:

type Base =
    abstract func : int * int -> int

    default this.func (x : int, y : int) : int =
        x + y

You can even shorten it a bit:

default this.func(x, y) = x + y

Upvotes: 5

Tomas Petricek
Tomas Petricek

Reputation: 243051

To get the first version to compile, you need to write:

type Base1 =
    abstract func : (int * int) -> int
    default this.func( (x : int, y : int) ) : int =
        x + y

I don't have a link to the specification, but F# doesn't generally compile members as methods that take tuples as arguments. It usually uses .NET/C# friendly method with multiple arguments. The abstract member enforces this representation, so the default member needs to do the same using a more explicit syntax.

You're correct in understanding the second type - the second declaration is an abstract class with unimplemented abstract method (and another method that happens to have the same name). For this, F# requires AbstractClass attribute (it doesn't require it for the above, because it is not abstract).

Upvotes: 4

Related Questions