在 OCaml 中,[@tailcall]
注释可以让您断言特定的函数调用是尾调用(因此希望您的整个函数是尾递归的)。问题是:我应该将注释准确放置在哪里?
明显、简单的例子:
let rec f = function
| 0 -> 0
| x -> (f [@tailcall]) (x - 1) (* works like a charm *)
Run Code Online (Sandbox Code Playgroud)
但我不知道如何在“不太明显”的地方做到这一点:
let rec f = function
| 0 -> 0
| x -> (|>) (x - 1) f (* uh? *)
Run Code Online (Sandbox Code Playgroud)
从汇编代码中我可以看到,后一个示例被编译器识别为尾递归。所以直到有人实现[@tailrec]
:我到底应该在哪里放置[@tailcall]
注释?(如果在第二个例子中可能的话)
当从多个模块创建一个库时,我找不到一种很好的方法来向库的用户(外部接口)隐藏正确的信息,同时能够在内部接口上访问我需要的一切。
更具体地说,我有两个模块(文件 a.ml[i] 和 b.ml[i])。在 A 中,我定义了一些类型 t,这是我不想向用户隐藏的内部结构(外部接口)。
module A : sig
type t
end
module A = struct
type t = float
end
Run Code Online (Sandbox Code Playgroud)
在模块B,然后我想用秘密类型A.t
。
module B : sig
create_a : float -> A.t
end
module B = struct
create_a x = x
end
Run Code Online (Sandbox Code Playgroud)
这当然不会编译,因为 B 的编译单元不知道A.t
.
我知道但不喜欢的解决方案:
create_a
移至模块A
A.t
to的定义B
并用一些欺骗类型检查器external cheat : `a -> `b = "%identity"
有没有其他方法可以A.t
在B
不将此信息泄漏到图书馆界面的情况下了解in的类型?