F# 选项链

rwa*_*ace 2 f#

F# 选项类型是从函数返回“结果或失败”的好方法。

有时您需要按照以下方式链接这些函数:

  1. 调用第一个函数
  2. 如果它返回 Somewhatever,则将whatever传递给第二个函数并返回结果
  3. 否则,立即返回 None

当然这可以通过模式匹配来完成;来自本身以这种方式实现模式匹配的函数的实际代码片段:

    match mtch env a0 a1 with
    |Some env->
        mtch env b0 b1
    |None->
        None
Run Code Online (Sandbox Code Playgroud)

但感觉应该有一种更紧凑的方式来表达这个常见的习惯用法,也许使用更高阶的函数。有这样的事吗?

kae*_*fer 6

FSharp.Core 中有一个Option模块,提供“选项的基本操作”。具体来说, 的签名与Option.bind您的用例相匹配:

活页夹:('T -> 'U 选项) -> 选项:'T 选项 -> 'U 选项

它在 VisualStudio 弹出提示中指出bind f inp evaluates to match inp with None -> None | Some x -> f x.

// The actual argument values are not important here
let env, a0, a1, b0, b1 = (), (), (), (), () 
let mtch env _ _ = Some env // or might be None

match mtch env a0 a1 with
|Some env -> mtch env b0 b1
|None -> None

mtch env a0 a1
|> Option.bind (fun env -> mtch env b0 b1)
Run Code Online (Sandbox Code Playgroud)

您甚至可以通过为选项操作定义自定义运算符来改进这一点。

let (>>=) ma f = Option.bind f ma
let (>>.) ma f = Option.map f ma

mtch env a0 a1
>>= fun env -> mtch env b0 b1
>>= ...
Run Code Online (Sandbox Code Playgroud)