【问题标题】:How do I read this piece of OCaml code that uses "~" and ":"?如何阅读这段使用“~”和“:”的 OCaml 代码?
【发布时间】:2023-03-26 00:41:01
【问题描述】:

我是 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??

【问题讨论】:

  • 代码不完整。它甚至在语法上都不是有效的。但即使是这样,不知道Mm 是什么也很难解释。可以合理地假设 M.bind 是一元绑定,就像您所做的那样,而且很明显 M.bind 通过 fresult,但很难说更多。
  • 我也不知道第二次计算被“标记”是什么意思。但是其中的f 引用了catch 的参数,而不是M.bind 定义的任何内容。
  • @glennsl:代码是一个较大文件的一部分,它肯定可以编译。我只是没有提供额外的上下文。
  • 您应该始终提供minimal reproducible example

标签: ocaml


【解决方案1】:

带标签的参数与特定函数相关联。这意味着该函数有一个带名称的参数。调用该函数时,您可以像这样指定名称和值:

 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

所以我们知道关于这个函数的一切。它绝对没有任何命名参数。

【讨论】:

  • 所以如果我理解正确的话,bind 的第二个参数(它必须是一个给定绑定类型的函数)在这种情况下被标记为 f?我的语言也很草率——我应该说“形式参数”而不是“参数”——所以我认为你所说的不仅仅是可以命名的形式参数,还有参数。这样一来,事情就更清楚了,尽管“f”的重用似乎仍然可能引起混乱。
  • 一个函数要么有命名参数,要么没有。如果它具有命名参数,那么当您调用该函数时,您会提供名称。调用函数时提供的名称必须与函数定义接受的名称相同。据我所知,没有真正可能的混淆。
  • 在我看来你没有理解这个想法的本质:如果一个函数是用命名参数定义的,那么调用者在进行调用时需要提供这些确切的名称。但是参数可以以任何顺序出现。 (事实上​​,我们可以稍后再讨论一些复杂性。)
  • 好的,你的最后一条评论终于解决了我的困惑,谢谢,但我认为造成一些困惑的是,当你在第一条评论中说“论点”时,我认为你的意思是“参数”。那就是“一个函数要么有命名参数,要么没有......”然后当您调用该函数时,您提供的参数也必须具有与其相应参数(如果有)相同的标签。我希望我现在拥有它。
猜你喜欢
  • 1970-01-01
  • 2014-02-20
  • 2010-12-02
  • 2012-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多