31

This is the typical declaration of an abstract member in F#:

abstract member createEmployee : string -> string -> Employee

You define the argument types but not their names. Without names, how do you tell what each parameter is when you implement the interface? In other words, how do you know if the interface expects to be implemented as 1- or 2-?

1-   member this.createEmployee firstName lastName = ...
2-   member this.createEmployee lastName firstName = ...

Am I looking the problem from a wrong perspective (being used to C#)?

Francesco De Vittori
  • 9,100
  • 6
  • 33
  • 43

2 Answers2

46

What about:

abstract member createEmployee : firstName:string -> lastName:string -> Employee

?

Ramon Snir
  • 7,520
  • 3
  • 43
  • 61
  • 5
    Thanks, this is slightly embarassing :-), I've never seen before examples with named params in the online doc. – Francesco De Vittori Sep 21 '11 at 07:23
  • 18
    What is interesting is that it's an error to wrap the pairs of parameter name & type in brackets like you would when specifying type for function parameters such as: `abstract member createEmployee : (firstName:string) -> (lastName:string) -> Employee` – Daniel Bradley Sep 02 '14 at 11:09
12

The syntax for this is super fiddly IMO. I wanted to do this with the parameters as a tuple (like a C# method) and only through trial and error did I find this to work:

    abstract member PutChar : x:int * y:int * c:char * flag:Background -> unit

And this uglier variant also works:

    abstract member PutChar : x : int * y : int * c : char * flag : Background -> unit

Below are things that all felt reasonable but failed with the same error - Unexpected symbol ':' in member definition.:

    // ALL BAD vvv
    abstract member PutChar : (x:int * y:int * c:char * flag:Background) -> unit
    abstract member PutChar : (x:int, y:int, c:char, flag:Background) -> unit
    abstract member PutChar : (x:int) * (y:int) * (c:char) * (flag:Background) -> unit
    // ALL BAD ^^^
JHo
  • 456
  • 4
  • 6
  • Without the parameter names, the first invalid variant would be compiled to a CLI method that takes one argument that happens to be a tuple. That is a notably different signature to a 4-argument CLI method; you can't name the components of tuples that are nested like this. The second is syntactically invalid; the comma isn't used on types this way. I don't know why the third isn't allowed. – Vandroiy Mar 06 '16 at 10:41