What would be the idiomatic F# way to write optional parameters? In the context of a library to generate random credit card, it would be nice to let the user the possibility to set some optional options on some cards. Lets take Visa. Two lengths are available: 13 or 16 digits.
In C# a common implementation would be:
enum VisaLengthOptions
{
    Thirteen,
    Sixteen
}

public static string GenerateVisa(VisaLengthOptions length = VisaLengthOptions.Sixteen) {
    if (length == VisaLengthOptions.Thirteen) return &quot;4000000000001&quot;;
    if (length == VisaLengthOptions.Sixteen) return &quot;4000000000000001&quot;;
    return &quot;&quot;;
}

Since F# does not support optional parameter (for currying and simplicity reason (note that it could be done since ocaml did it)). What would be the most idiomatic way to write this in F#?
Here is a guess:
type VisaLengthOptions =
    | Thirteen = 0
    | Sixteen = 1

let constructVisa length =
    match length with
    | VisaLengthOptions.Thirteen -&gt; &quot;4000000000001&quot;
    | VisaLengthOptions.Sixteen -&gt; &quot;4000000000000001&quot;
    | _ -&gt; &quot;&quot;

let generateVisa () = constructVisa VisaLengthOptions.Sixteen

So there are no optional parameter and have two functions cant have the same name even with different signatures. What wrong with this snippet?
We want our library to have a Truly Discoverable API. So we would like to avoid having two different name for basically the same logic. Should we follow the map and map2 and goes generateVisa and generateVisa2? or like map and mapi and goes generateVisa and generateVisaL? Is there a one true F# way?
A good example in the .net world is Split.
I would argue that if you need optional parameters your interface is different hence you need another function.
With that said, if you really want optional parameters you must always define a default value, an you could then use partial application for that.
let f op1 op2 nonOpt = op1 + op2 + nonOpt

let fWithDefaults = f 1 2

Then you can use your fWithDefaults whenever you want the defaults.
For your particular example I would write it like this :
type VisaLengths = 
     | Thirteen
     | Sixteen

let generateVisa (length : VisaLengths option) =
     let length = Option.defaultValue Sixteen length
     match length with
     | Thirteen -&gt; &quot;4000000000001&quot;
     | Sixteen -&gt; &quot;4000000000000001&quot;
      

It would be the most &quot;idiomatic&quot;, even if it can be a litter cumbersome but it does what you want to do.
Agree, you still have to passe None... But at least your intention about a optional value is explicit, which is very valuable for others reading your code.