代码之家  ›  专栏  ›  技术社区  ›  Homan

理解ReasonML中的Js.Promise.resolve(.)点语法

  •  2
  • Homan  · 技术社区  · 6 年前

    我正在努力理解这些文档: https://reasonml.github.io/docs/en/promise

    在用法部分,有:

    let myPromise = Js.Promise.make((~resolve, ~reject) => resolve(. 2));
    

    为什么在2之前有点?这意味着什么?它有什么作用?

    1 回复  |  直到 6 年前
        1
  •  6
  •   glennsl Namudon'tdie    6 年前

    (. ) 正如这里所使用的,在函数应用程序中,意味着应该使用无载波调用约定调用函数。

    在函数类型中使用时,如 resolve (. 'a) => unit ,这意味着该函数是未载波的。

    什么是未结婚?

    不结婚是咖喱的反面,让我们先解释一下,然后比较一下。

    curry是将一个包含多个参数的函数转换为一系列函数的过程,每个函数只包含一个参数,并返回最终返回值或包含下一个参数的函数。在Reason/OCaml中,这是为我们自动完成的,这也是为什么在OCaml中,函数类型在其参数之间有箭头(例如。 'a -> 'b -> 'ret )。您也可以用这种方式编写函数类型( 'a => 'b => 'ret ),但默认情况下,它被语法隐藏( ('a, 'b) => 'ret ),这一点很好,但也可能使我们更难理解为什么函数在某些情况下会出现意外行为。

    let add = (a, b) => a + b;
    

    这是它的咖喱形式:

    let add = a => b => a + b;
    

    并用括号强调单独的功能:

    let add = a => (b => a + b);
    

    a ,然后返回一个函数(关闭 b 然后计算最终的返回值。

    A. 不使用 bind

    let result = add(2)(3);
    

    因此,Reason/OCaml不仅在创建时自动执行curry函数,而且还提供了 这也让我们可以方便地应用多个参数。

    这一切都很好。。。只要每个函数都是咖喱。但接下来我们想与JavaScript交流,而大多数函数都不是这样(但有一个值得注意的例外,请参见Ramda)。为了能够调用uncurried JavaScript函数,我们需要一个uncurried 呼叫约定 ,并且为了能够创建可以按预期从JavaScript调用的函数,我们需要一个无载波的 .

    为什么 决定 需要不结婚吗?

    让我们看看你的完整签名 Js.Promise.make ,这很有趣,因为它包括三种未载波函数:

    [@bs.new]
    external make :
        ([@bs.uncurry] (
            (~resolve: (. 'a) => unit,
             ~reject: (. exn) => unit) => unit)) => t('a) = "Promise";
    

    或者使用OCaml语法,在本例中,我发现其可读性更高:

    external make : (resolve:('a -> unit [@bs]) ->
                     reject:(exn -> unit [@bs]) -> unit [@bs.uncurry]) -> 'a t = "Promise" [@@bs.new]
    

    第一类函数是 make 它本身是外部的,可以推断为未绑定,因为所有外部当然都是用JavaScript实现的。

    第二类函数是我们将创建并传递给的回调函数 制作 . 这必须是无载波的,因为它是使用无载波调用约定从JavaScript调用的。但是由于我们创建的函数是默认的, [@bs.uncurry]

    决定 reject ,它们是从JavaScript传回的回调函数,因此未进行传输。但这些也是一元函数,你会认为咖喱和未咖喱的形式应该完全相同。对于普通的单态函数,你是对的,但不幸的是 是多态的,这会产生一些问题。

    我认为问题甚至比这更微妙。可能会出现这种情况,因为我们需要能够使用curried函数类型来表示0进制的无载波函数,这些函数类型都是1进制的。我们怎么做?如果要在Reason/OCaml中实现一个等价的函数,您应该使用 unit 作为参数类型,我们就这样做吧。但是现在,如果你有一个多态函数,如果它是单态的,它可能是0元的 单元 1-3,否则。我想用一个参数调用一个0元函数在某种程度上被认为是不合理的。

    拒绝


    有关详细信息,请参阅 the manual (但请注意,它混淆了curry和partial application)

    推荐文章