问题描述
我是 OCaml 的新手,在浏览一些代码时,我看到了以下内容:
let catch f m = M.bind m ~f:(
function Error e -> f e
| Ok x -
)
据我所知,这是定义一个 try/catch 块(我的理解是 OCaml 不使用单独的 catch 块)。 M.bind
是将 m 的结果传递给第二次计算的 monadic 绑定运算符。 OCaml 参考手册说 ~ 用于标记参数,以便于理解文档中的类型签名。然而,这是否意味着第二个计算(“function ..
”)也被标记为 f??
解决方法
带标签的参数与特定函数相关联。这意味着该函数有一个带有名称的参数。调用该函数时,请指定名称和值,如下所示:
myfun ~name: value
如果此调用有效,则我们知道 myfun
具有名称为 name
的参数。
为了比较,当你调用一个没有带标签参数的函数时,调用看起来像这样:
myotherfun othervalue
接受命名参数的函数定义如下所示:
let myfun ~name =
... expression involving name ...
例如,这个函数从你传递的任何东西中生成一个单例列表:
let myfun ~name = [name]
在 OCaml 顶层 (REPL) 中对该函数的调用如下所示:
# myfun ~name: 44;;
- : int list = [44]
关键是这允许您在调用函数时按名称而不是按位置指定参数。您需要指定函数期望的名称。但是如果一个函数有多个命名参数,你可以按任意顺序指定它们。
这些名称仅用于 OCaml 文档是不正确的。手册告诉你的是,命名参数作为关于不同参数的用途的良好文档。对于带有大量参数的函数尤其如此,尤其是当其中一些是相同类型的函数时更是如此。使用名称可以避免以错误顺序指定名称的错误。
因此,您正在调用具有名称为 M.bind
的标记参数的函数 f
。传统上,名为 f
的参数用于将函数作为参数传递,这确实是这里发生的事情。
所以;你的问题似乎是第二个参数是否被标记。 M.bind
的第二个参数被标记为是。但价值可以是任何东西。值不受传递给它的函数标签的影响。此外,您可以查看函数定义 function Error ...
并看到它没有任何带标签的参数。它只是一个接受 result
类型值的函数。
重复一遍,这是一个函数定义:
function Error -> f e | Ok x -> g x
所以我们知道关于这个函数的一切。它绝对没有任何命名参数。