Search code examples
f#naming

Name for function like Option.bind that returns Some(x) when input is None


The normal Option.bind function is defined like this:

// ('T -> 'U option) -> 'T option -> 'U option
let bind f x =
    match x with
    | None -> None
    | Some x' -> f x'

I am in need of a slightly different version of this:

// ('T -> 'U -> 'U option) -> 'T option -> ('U -> 'U option)
let myBind f x =
    match x with
    | None -> Some
    | Some x' -> f x'

Does this function have a standard name? (If not I'll gladly accept concise suggestions.)


For interested readers, my usecase is this: I have a business object (say Order) I want to apply a constraint to (order date, customer, etc.). The functions that apply constraints to e.g. an Order have signature 'Constraint -> Order -> Order option. They return Some order if the order passed the constraint, and None otherwise (and can thus be composed using Option.bind). Now, if the constraint is None, it's essentially a no-op and Some order should be returned. Instead of having all constraint functions accept 'Constraint option I can factor out this part of the logic using the function above (which then need to be applied during composition).

I originally called the function something like bindConstraint, but it's completely generic and really has nothing to do with my usecase (ref. Mark Seemann's article on the topic). Due to its similarity with bind I wondered if there is a standard name for this.


Solution

  • Let's look at your function type signature:

    // ('T -> 'U -> 'U option) -> 'T option -> ('U -> 'U option)
    

    The 'U -> 'U option type can actually be factored out of that signature. Let's call that type 'V. Then the type signature becomes:

    // ('T -> 'V) -> 'T option -> 'V
    

    Which looks rather similar to Option.map, whose signature is:

    // ('T -> 'V) -> 'T option -> 'V option
    

    So basically, your function is equivalent to Option.map followed by a defaultArg to turn that 'V option into a 'V (supplying a default value if the option was None).

    So I'd probably call it something like defaultMap or mapDefault.