我如何柯里化一个带有可选参数的函数,该函数在 ReasionML/BuckleScript 中生成 Js.t 个对象?

How can I curry a function with optional parameters that generates Js.t objects in ReasionML/BuckleScript?

我有以下功能

[@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}

我做错了什么?

这实际上不是关于可选参数和柯里化,而是关于值限制和非广义的,也就是弱类型变量。长话短说;博士;要么通过添加参数将 get 转换为句法函数,例如 let get () = route(~_method="GET") ();,或者为您的模块创建一个 *.rei 接口文件。

长话短说

.. 表示编译器无法将其简化为普通单态类型的多态类型(因为显然没有使用此函数),也不能相信部分应用程序 route(~_method="GET") 实际上还没有访问 options 参数,可能存储在其中的某处,应该定义类型。

因此,编译器,不能把它留作多态变量,也不能给出具体的类型,结果就产生了一个弱类型变量,可以作为以后的参考单元格定义的具体类型。就像一个未初始化的类型。稍后将通过使用 get 函数的代码对其进行初始化。如果在一天结束时,该类型从未被使用过,它可能会逃出模块的范围,这是 OCaml/Reason 类型规则所禁止的。因此,您应该手动给它一个单型(即,将其约束为某种单态类型),或者创建一个隐藏该值的接口文件(即,不存在),因此不能泄漏模块的范围。基本上,只需创建一个与 .ml/.re 文件同名的空 .mli/.rei 文件即可解决此问题。另一种常见的解决方案是将 get 变成语法函数,即具有语法显式变量的东西,例如

let get () = route(~_method="GET") ();

进一步阅读