Ruby 为什么必须为curry显式指定两个参数:>;

Ruby 为什么必须为curry显式指定两个参数:>;,ruby,Ruby,考虑一下这一点,效果很好: :>.to_proc.curry(2)[9][8] #=> true, because 9 > 8 但是,即使>是一个二进制运算符,如果没有指定的arity,上述操作也无法工作: :>.to_proc.curry[9][8] #=> ArgumentError: wrong number of arguments (0 for 1) 为什么两者不相等 注意:我特别想用提供的一个参数创建中间curry函数,然后用第二个参数调用它。cur

考虑一下这一点,效果很好:

:>.to_proc.curry(2)[9][8] #=> true, because 9 > 8
但是,即使
>
是一个二进制运算符,如果没有指定的arity,上述操作也无法工作:

:>.to_proc.curry[9][8] #=> ArgumentError: wrong number of arguments (0 for 1)
为什么两者不相等


注意:我特别想用提供的一个参数创建中间curry函数,然后用第二个参数调用它。

curry必须知道传入过程的算术性,对吗

 :<.to_proc.arity  # => -1
当你创建一个lambda表示它需要两个参数时,它知道它需要两个参数,并且可以很好地使用这种调用#curry的方式


但是当你使用符号“to”proc技巧时,它只是有一个符号,它不知道需要多少参数。虽然我不认为
我认为这是因为
Symbol#to_proc
创建了一个带有一个参数的proc。当转换为进程时,
:>
看起来不像:

->x, y{...}
但它看起来像:

->x{...}
由于
的原始单参数要求以某种方式隐藏在proc主体中(请注意,
不是一个接受两个参数的方法,它是一个使用一个参数在一个接收器上调用的方法)。其实,

:>.to_proc.arity # => -1
->x, y{}.arity # => 2
这意味着不加争论地使用
curry
只会产生微不足道的效果;它接受带有一个参数的proc,并返回自身。通过显式指定
2
,它可以做一些非常重要的事情。为了进行比较,请考虑<代码>连接< /代码>:

:join.to_proc.arity # => -1
:join.to_proc.call(["x", "y"]) # => "xy"
:join.to_proc.curry.call(["x", "y"]) # => "xy"

请注意,在curry
:join
之后提供单个参数已经对整个方法进行了评估。

@jrochkind的回答很好地解释了为什么
:>。to_proc.curry
没有您想要的行为。不过,我想说的是,你问题的这一部分有一个解决方案:

我特别想用一个参数创建中间curried函数,然后用第二个参数调用它

解决办法是。与此相反:

nine_is_greater_than = :>.to_proc.curry[9]
nine_is_greater_than[8]
#=> ArgumentError: wrong number of arguments (0 for 1)
…这样做:

nine_is_greater_than = 9.method(:>)
nine_is_greater_than[8]
# => true
Object#方法
返回一个对象,它的行为就像一个进程:它响应
调用
[]
,甚至(从Ruby 2.2开始)
curry
。但是,如果您需要一个真正的proc(或者想在Ruby<2.2中使用
curry
),您也可以在其上调用
to_proc
(或者使用
&
,to_proc
操作符):


我认为在您的
def to_proc
中,您应该将
lambda
更改为
proc
。好的,我不知道它使用哪种,也不确定它是否会对实现使用哪种产生任何影响(我认为不会),但如果您这样认为,我将更改它!它使用
proc
。您可以通过检查
:>。to_proc.lambda?
,返回
false
。我刚才说过它看起来像这样,呵呵。我认为如果它是lambda或proc,它的功能是相同的,这没有什么区别(我想?),但我已经根据您的请求编辑了我的示例,谢谢!伪代码让我把一切都整合在一起了。谢谢谢谢你的回答。事实上,我已经知道这个把戏了,我主要是想了解咖喱是如何工作的,但我认为这是一个很好的答案,对于其他偶然发现这个问题的人来说。
:>.to_proc.arity # => -1
->x, y{}.arity # => 2
:join.to_proc.arity # => -1
:join.to_proc.call(["x", "y"]) # => "xy"
:join.to_proc.curry.call(["x", "y"]) # => "xy"
nine_is_greater_than = :>.to_proc.curry[9]
nine_is_greater_than[8]
#=> ArgumentError: wrong number of arguments (0 for 1)
nine_is_greater_than = 9.method(:>)
nine_is_greater_than[8]
# => true
[ 1, 4, 8, 10, 20, 30 ].map(&nine_is_greater_than)
# => [ true, true, true, false, false, false ]