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

How to bind a whole module as a function?

我在玩理性游戏,我想尝试为 debug 做 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.

instance 不是应该绑定到一个函数吗?我也试过

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

open Debug;    
let instance = Debug.createDebug "app";    
instance.write "Hello World !!!";

但我得到

Error: Unbound record field write

我错过了什么?

createDebug函数,根据你的声明,returns一个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