haskell - OCaml 参数传递方案中的断点

标签 haskell ocaml ocaml-core

今天在看Jane Street的源码的Core_kernel模块和我 came across compose功能:

(* The typical use case for these functions is to pass in functional arguments
   and get functions as a result. For this reason, we tell the compiler where
   to insert breakpoints in the argument-passing scheme. *)
let compose f g = (); fun x -> f (g x)

我会定义 compose功能为:

let compose f g x = f (g x)

他们给出定义 compose 的原因他们的做法是“因为 compose是一个函数,它采用函数 fg作为参数并返回函数fun x -> f (g x)结果,他们定义了compose他们告诉编译器在 f 之后插入断点的方式和 g但在 x 之前在参数传递方案中。”

所以我有两个问题:
  • 为什么我们需要在参数传递方案中设置断点?
  • 如果我们定义 compose 会有什么不同?正常的方式?

  • 来自 Haskell,这个约定对我来说没有任何意义。

    最佳答案

    这是一种效率技巧,可以避免在评论中指出的预期用例中部分应用程序的成本。

    OCaml 将柯里化(Currying)函数编译成固定数量的构造,在必要时使用闭包部分应用它们。这意味着该数量的调用是有效的——没有闭包构造,只是一个函数调用。
    compose 内将有一个封闭结构对于 fun x -> f (g x) ,但这会比部分应用更有效。部分应用程序生成的闭包通过包装器 caml_curryN它的存在是为了确保效果在正确的时间发生(如果该关闭本身已部分应用)。

    编译器选择的固定数量是基于简单的句法分析 - 本质上,有多少个参数连续被采用,中间没有任何东西。 Jane St. 的程序员通过注入(inject) () 使用它来选择他们想要的数量。 “介于两者之间”的论点。

    简而言之,let compose f g x = f (g x)是一个不太理想的定义,因为它会导致常见的两个参数情况 compose f g是一个更昂贵的部分应用程序。

    当然,语义上完全没有区别。

    关于haskell - OCaml 参数传递方案中的断点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29191484/

    相关文章:

    module - 在 OCaml 中获取脚本名称?

    memory - 如何在 Haskell 中获取指针值?

    haskell - 你如何在 Haskell 的实例方法中应用函数约束?

    haskell - 确定总的终止函数

    ocaml - Core_kernel.Heap 和 Core_kernel.FHeap 有什么区别?

    ocaml - Jane Street 的 ‘Base’ 、 ‘Core’ 和 'Core_kernel' 有什么区别?

    haskell - `Data.Text` 与 `Data.Vector.Unboxed Char`

    ocaml - Cstruct 和 Lwt_bytes

    interface - 具有不同特异性水平的 OCaml 类型