我具有以下功能
[@bs.obj]
external route:
(
~_method: string,
~path: string,
~action: list(string) => unit,
~options: Js.t({..})=?,
unit
) =>
_ =
"";
由于可以部分应用函数,所以我希望能够做到这一点:
let get = route(~_method="GET");
但是它给了我这个错误:
This expression's type contains type variables that can't be generalized:
(~path: string, ~action: list(string) => unit, ~options: {_.. }=?,
unit) =>
{. "_method": string, "action": list(string) => unit,
"options": Js.undefined({.. }), "path": string}
我在这里做什么错了?
答案 0 :(得分:4)
这实际上与可选参数和curring无关,而是与值限制和非通用(即弱)类型变量有关。 TL; DR;通过添加参数get
将let get () = route(~_method="GET") ();
转换为语法函数,或为模块创建*.rei
接口文件。
..
row variable表示一种多态类型,编译器无法将其简化为正常的单态类型(因为显然没有使用此函数),也不能相信部分应用程序{ {1}}实际上尚未访问route(~_method="GET")
参数,可以将其存储在其中的某个位置,该参数应定义类型。
因此,编译器不能将其保留为多态变量,也不能提供具体类型,因此,它会生成弱类型变量,可以将其视为将来定义的具体混凝土的参考单元类型。就像未初始化的类型。稍后将通过使用options
函数的代码对其进行初始化。如果最终没有使用过该类型,则可能会超出OCaml / Reason输入规则所禁止的模块范围。因此,您应该手动为它指定一个单型(即将其约束为某种单态类型),或者创建一个隐藏该值(即不存在)的接口文件,因此不会泄漏模块的范围。基本上,仅创建一个与您的get
文件同名的空.mli/.rei
文件即可解决此问题。另一个常见的解决方案是将.ml/.re
转换为语法函数,即带有语法显式变量的内容,例如
get