(. )
正如这里所使用的,在函数应用程序中,意味着应该使用无载波调用约定调用函数。
在函数类型中使用时,如
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)