Ocaml 如何将整个模块绑定为函数?

Ocaml 如何将整个模块绑定为函数?,ocaml,ffi,reason,bucklescript,Ocaml,Ffi,Reason,Bucklescript,我在玩弄理性,我想尝试做FFI的调试,以便学习。我有这个密码 module Instance = { type t; external t : t = "" [@@bs.module]; }; module Debug = { type t; external createDebug : string => Instance.t = "debug" [@@bs.module]; }; 我正试着这样使用它 open Debug; let instance = De

我在玩弄理性,我想尝试做FFI的调试,以便学习。我有这个密码

module Instance = {
  type t;
  external t : t = "" [@@bs.module];
};

module Debug = {
  type t;
  external createDebug : string => Instance.t = "debug" [@@bs.module];
};
我正试着这样使用它

open Debug;    
let instance = Debug.createDebug "app";
instance "Hello World !!!";
但是我得到了以下错误

Error: This expression has type Debug.Instance.t
       This is not a function; it cannot be applied.
实例不应该绑定到函数吗?我也试过了

module Instance = {
  type t;
  external write : string => unit = "" [@@bs.send];
};

但我明白了

Error: Unbound record field write
我缺少什么?

根据您的声明,createDebug函数返回Instance.t类型的值。从某种意义上说,它是一个抽象值,对它的实现一无所知,只能通过它的接口使用它。类型的接口基本上是允许您操作此类型的值的所有值函数。在您的例子中,我们只能找到两个这样的值-Instance.t值和Debug.createDebug函数。根据您自己的声明,这两者都可以用来创建这样的价值。没有提供使用它的功能

可能您对什么是模块有些误解。它本身不是一个对象,而是一个名称空间。它就像一个文件中的一个文件

第二个示例证明您考虑的是模块,因为它们是一种运行时对象或记录。但是,它们只是用于将大型程序组织到分层名称空间中的静态结构

您试图使用的实际上是一个记录:

type debug = { write : string => unit }

let create_debug service => {
  write: fun msg => print_endline (service ^ ": " ^ msg)
}

let debug = create_debug "server"
debug.write "started"
将产生:

server: started

t是在模块实例中定义的抽象类型。它不是一种模块类型。如果你真的想把模块当作值来处理,你必须使用一流的模块。谢谢。但是,如果我在实例模块中定义了一个外部命令,比如外部写入:string=>unit=[@@bs.send];,为什么我不能调用.write?因为createDebug不创建模块的实例,所以没有理由这样做,它创建了一个t类型的实例,而函数write与t类型无关。它使用字符串而不是t。我已经用一个例子更新了我的答案,这将推动你朝着正确的方向前进:
server: started