Guy
Guy

Reputation: 110

Optional parameter type mismatch

I'm working with F# 3.1 and I've twice today come across a compile error I can't explain and have had no luck looking up.

In the following code:

type OtherClass(value:int, ?flag:bool) =
    member this.DoSomething = (value,flag)
and
MyClass(value:int, ?flag:bool) =
   let _dummy = new OtherClass(value,flag)

The compiler says that in my MyClass where I make the call to OtherClass's ctor, the type of flag is incorrect. Specifically, it says that it wants a bool, not a bool option. Yet, it is defined as a bool option according to all that I can see.

Any idea why flag is being seen as a regular bool, and not a bool option as its defined?

Edit:

Upon further reflection, I guess I know whats going on. Optional parameters are inside the method treated as option, but outside, they want the real thing. Something swaps the value out on the call to an option type. So that means that to do what i was trying to do we need something like this

type OtherClass(value:int, ?flag:bool) =
    member this.DoSomething = (value,flag)
and
MyClass(value:int, ?flag:bool) =
let _dummy =
    match flag with 
    | None -> new OtherClass(value)
    | Some(p) -> new OtherClass(value, p)

This works, but seems a bit verbose. Is there a way to pass an optional directly into an optional parameter like this without resorting to different calls?

Upvotes: 3

Views: 284

Answers (1)

Daniel
Daniel

Reputation: 47914

Here's the way to do this:

type 
  OtherClass(value:int, ?flag:bool) =
    member this.DoSomething = (value,flag)
and 
  MyClass(value:int, ?flag:bool) =
    let _dummy = new OtherClass(value, ?flag=flag)

Quoting §8.13.6 of the spec:

Callers may specify values for optional arguments in the following ways:

  • By propagating an existing optional value by name, such as ?arg2=None or ?arg2=Some(3) or ?arg2=arg2. This can be useful when building a method that passes optional arguments on to another method.

Upvotes: 3

Related Questions