如何阅读这段使用“~”和“:”的 OCaml 代码?
How do I read this piece of OCaml code that uses "~" and ":"?
我是 OCaml 的新手,在浏览一些代码时我看到了以下内容:
let catch f m = M.bind m ~f:(
function Error e -> f e
| Ok x -
)
据我所知,这是在定义一个 try/catch 块(我的理解是 OCaml 不使用单独的 catch 块)。 M.bind
是将 m 的结果传递给第二次计算的单子绑定运算符。 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
所以我们知道关于这个函数的一切。它绝对没有任何命名参数。
我是 OCaml 的新手,在浏览一些代码时我看到了以下内容:
let catch f m = M.bind m ~f:(
function Error e -> f e
| Ok x -
)
据我所知,这是在定义一个 try/catch 块(我的理解是 OCaml 不使用单独的 catch 块)。 M.bind
是将 m 的结果传递给第二次计算的单子绑定运算符。 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
所以我们知道关于这个函数的一切。它绝对没有任何命名参数。