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 ]