我如何使用可选参数curry函数,该函数在Reasionml/bucklescript中生成JS.T对象



i具有以下功能

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

我在这里做错了什么?

这实际上不是关于可选参数和咖喱的,而是关于值限制和非征服的,又称弱的类型变量。tl; dr;通过添加参数(例如let get () = route(~_method="GET") ();)将get变成句法函数,或为模块创建*.rei接口文件。

更长的故事

..行变量表示编译器无法将其降低到正常单态类型的多态性类型(由于显然没有使用此功能),也可以相信部分应用程序route(~_method="GET")实际上尚未访问options参数可以存储在其中的某个地方,该参数应定义类型。

因此,编译器不能将其作为多态变量,也无法给出混凝土类型,因此,它会产生一个弱类型变量,可以看作是未来定义的混凝土的参考单元类型。像非初始化的类型。它将在稍后通过使用get函数的代码初始化。如果在一天结束时从未使用过类型,则可能会逃脱模块的范围,该模块被OCAML/PROASIN打字规则禁止。因此,您要么手动给出一个单型(即,将其限制为某些单态类型),要么创建一个接口文件,其中该值隐藏了(即不存在),因此无法泄漏模块的范围。基本上,仅创建一个与.ml/.re文件相同的名称的空.mli/.rei文件就可以解决此问题。另一个常见的解决方案是将get变成句法函数,即具有句法显式变量的内容,例如,

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

进一步阅读

  • https://ocamlverse.github.io/content/weak_type_variables.html
  • http://caml.inria.fr/pub/docs/manual-ocaml/polymorphism.html#sec51
  • https://v1.realworldocaml.org/v1/en/html/imperative-programming-1.html#side-effect-side-effects-and-weak-weak-polymormormormormormormormporm

相关内容

  • 没有找到相关文章

最新更新