`String.sub` 的这个签名是什么意思:`(string, string) Blit.sub`

What is the meaning of this signature for `String.sub`: `(string, string) Blit.sub`

我正在 utop 中学习/玩 ocaml。继 real world ocaml book.

所以我很自然地开始了:

open Base;;

接下来我试试:

utop # String.sub "Hello world!" 3 4;;
Line 1, characters 0-10:
Warning 6 [labels-omitted]: labels pos, len were omitted in the application of this function.
Line 1, characters 0-10:
Warning 6 [labels-omitted]: labels pos, len were omitted in the application of this function.
- : string = "lo w"

好的,大致符合预期。 Base 将许多标准函数(如 String.sub 替换为使用带标签参数的版本以清晰起见(可以说是一件好事,所以我真的没有抱怨)。

但这就是让我感到困惑的地方。当我尝试检查改进后的 String.sub 的签名/类型时,我希望看到一个类似于 'standard' String.sub 签名(string -> int -> int -> string)但带有标签的改进函数签名争论。我看到的是:

utop # String.sub;;
- : (string, string) Blit.sub = <fun>

这是什么意思?以及(天真的)用户如何使用它来确定调用 String.sub 函数的正确方法?

即我如何从 (string, string) Blit.sub...

这样的签名中找出答案

Blit.sub 是函数类型的类型别名。但是让我们自己去发现吧。我们可以在输出上使用 #show 指令来检查其类型,直到我们得到满意的结果,

# #show String.sub;;
val sub : (Base.String.t, Base.String.t) Base__.Blit.sub
# #show Base__.Blit.sub;;
type ('src, 'dst) sub = ('src, 'dst) Base__.Blit_intf.sub
# #show Base__.Blit_intf.sub;;
type ('src, 'dst) sub = 'src -> pos:int -> len:int -> 'dst

现在让我们用 string 替换 'src'dst 参数,因为我们有 (string, string) sub,我们得到 String.sub 的类型

String.sub : string -> pos:int -> len:int -> string

如果您使用 merlin 和合适的代码编辑器,这会容易得多。你可以让编辑器展开类型,这样需要几毫秒才能到达根,Merlin 也会为你进行替换。例如,在我的 Emacs 中,它只是 C-c C-t 在类型上的几次重复。对于可以通过一次击键轻松引入的文档来说也是如此(不过在这种情况下不是这样,因为此功能在 Base 中缺少文档)。您还可以轻松跳转到函数的定义或声明处。所以,如果你想在 OCaml 中发挥作用,请考虑设置一个良好的开发环境,如 Emacs、Vim、Visual Studio 代码或其他一些。