13

The following code does not compile.

type A(?arg) =
  member __.Arg : string option = arg

type B(?arg) =
  inherit A(arg) //ERROR expected type string but has type 'a option

I assume this is because an instance of the underlying type of the option must be provided, and the compiler handles passing Some/None based on syntax.

Assuming my assumption has been correctly assumed, is there a workaround for this? Is it possible to propagate optional arguments?

Daniel
  • 47,404
  • 11
  • 101
  • 179

3 Answers3

25

F# spec 8.13.5 Optional arguments to method members

Callers may specify values for optional arguments by using the following techniques:

  • By name, such as arg2 = 1.
  • 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 one method that passes optional arguments on to another.
  • By using normal, unnamed arguments matched by position.

    type A(?arg) =
        member __.Arg : string option = arg
    
    type B(?arg) =
        inherit A(?arg = arg) 
    
    printfn "1. %A" (B()).Arg // None
    printfn "2. %A" (B("1")).Arg // Some "1"
    
    printfn "3. %A" (A()).Arg // None
    printfn "4. %A" (A("1")).Arg // Some "1"
    
desco
  • 16,642
  • 1
  • 45
  • 56
  • Okay. You've read way too much of the spec. :-) Why does this work? – Daniel Aug 17 '11 at 16:01
  • Nevermind. I found it in the spec. I've _really_ got to read it some time. – Daniel Aug 17 '11 at 16:03
  • Interesting that two months ago I had a similar question (http://stackoverflow.com/questions/6353897/optional-parameters-and-option-types-using-f/7102689#7102689) but nobody could give me the correct answer. Thanks desco for your answer! – Oldrich Svec Aug 18 '11 at 05:19
0

Sorry had to test it first: it seems you are right - you have to do the "?" for A yourself:

type A(arg : string option) =
  new (a) = new A(Some a)
  new () = new A(None)
  member __.Arg : string option = arg

type B(?arg) =
  inherit A(arg)
Random Dev
  • 51,810
  • 9
  • 92
  • 119
  • That's workable. Thanks. I'll wait and see if anyone can suggest how to make it work while retaining the optional args on `A`. – Daniel Aug 17 '11 at 15:56
  • On second thought, this means optional args can't be propagated. You can't have a method or derived class with the same optional arg being passed to the constructor--kinda limiting. It would require branching to the correct constructor overload every time. – Daniel Aug 17 '11 at 15:59
  • might be a bug - inside the type arg (with ?) is string option, but in the definition of new it's string - maybe we should file a case? – Random Dev Aug 17 '11 at 16:03
-1

F# will translate ?-marked arguments to optional values. Providing an argument gives a Some-value while not providing it gives a None-value. The combination of optional and named arguments lets you have huge flexibility.

See also my answer here https://stackoverflow.com/a/66043023/15143713 /JEE, Sharp#Soft

  • The question is about how to propagate optional args to a base class. You merely pointed out something (the translation to Some/None) that was already stated in the question. – Daniel Feb 08 '21 at 22:12
  • Please look at my link. I do explain how to propagate optional arguments there. I did not want to repeat my answer twice. /JEE - Sharp and Soft – JEE - Sharp and Soft Feb 10 '21 at 18:16