Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Distinguishing between f# overloaded functions with optional parameters

Tags:

f#

F# allows overloaded functions to differ only by an optional parameter, for example:

type MyClass() = 
    member this.func(a: string, b:string) = "func(a,b)"
    member this.func(a: string, ?b:string) = "func(a,?b)"

How would you call the first function?

like image 582
Murray Avatar asked Apr 12 '17 04:04

Murray


1 Answers

I don't think there is a sensible way to call the first function if the two overloaded functions differ only by an optional parameter. As mentioned in the comments, using this is probably a poor design and you should rename the parameters.

As you probably noticed, when you try calling the function in an ordinary way using MyClass().func("A","B"), you get an error message complaining about the ambiguity:

error FS0041: A unique overload for method 'func' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: member MyClass.func : a:string * ?b:string -> string, member MyClass.func : a:string * b:string -> string

You can call the second overload explicitly in two ways (with or without ?b) thanks to the fact that you can explicitly provide Some value for an optional argument:

MyClass().func("A")
MyClass().func("A",?b=Some "B")

Out of curiosity, it turns out that you can call the first overload via a static member constraint. This is quite ugly and you probably shouldn't be doing this, but it calls the first overload:

let inline callFunc (o:^T) a b = 
  (^T : (member func : string * string -> string) (o, a, b)) 

callFunc (MyClass()) "A" "B"
like image 171
Tomas Petricek Avatar answered Oct 13 '22 23:10

Tomas Petricek