Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tupled arguments in interfaces

Tags:

f#

Can someone explain this F# curiosity?

    type IFoo =
        abstract member Bar1: int * int -> int * int
        abstract member Bar2: int * int -> (int * int)
        abstract member Bar3: (int * int) -> int * int

    type Foo() = class end
        with 
        interface IFoo with
            member this.Bar1 (x, y) = (x, y)
            member this.Bar2 (x, y) = (x, y) // Same impl as Bar1 i.e. parentheses on RHS of -> in interface member definition are ignored
            // member this.Bar3 (x, y) = (x, y) // Compile error: "This override takes a different number of arguments to the corresponding abstract member"
            member this.Bar3 tuple = tuple // So, parentheses on LHS of -> in interface member definition *does* make a difference!

What is the difference in meaning between the definitions of IFoo.Bar1 and IFoo.Bar3?

like image 867
Akash Avatar asked Nov 27 '14 13:11

Akash


1 Answers

Here, the input type can describe two different things: a tuple or the argument list of a CLI method.

This makes no difference on the return type, since the only interpretation of this return type is a tuple. But on the argument list, you can decide between a CLI method that takes two arguments, or a CLI method that takes one argument, which happens to be a tuple. The latter is denoted by the extra parentheses.

That is why you can implement Bar3 with a single argument, typed as a tuple, which isn't possible with the others (as of F# 3).

This is also a place where double parentheses make a difference to single parentheses. If Bar3 weren't abstract, you could enforce tuple input by declaring it as member this.Bar3 ((arg1, arg2)).

Method argument lists have additional features, such as optional arguments. So:

type Test () =
    member t.BarA(a, ?b) = a
    member t.BarT((a, ?b)) = a // Error

The last line gives the error "Optional arguments are only allowed on type members", since b is now part of a tuple pattern, not an argument in the method's argument list.

like image 166
Vandroiy Avatar answered Nov 16 '22 03:11

Vandroiy