我收到一条错误消息" method_object.rb:8:在`':错误的参数类型Fixnum(expect Proc)(TypeError)"尝试运行以下脚本时
def f(x,y=2)
x**y
end
a=method(:f).to_proc
b=a.curry.curry[4]
print 1.upto(5).map(&b)
puts
但是,如果以下列方式定义 function f ,则一切正常。
def f(x,y)
x**y
end
我的第一个代码出了什么问题会有人帮我吗?
答案 0 :(得分:5)
返回curried的proc。如果给出了可选的arity参数,则它确定参数的数量。 curried
proc
会收到一些参数。如果提供了足够数量的参数,它会将提供的参数传递给原始proc
,返回结果。否则,返回另一个带有其余参数的curried proc。
现在来看你的代码:
def f(x, y=2)
x**y
end
a = method(:f).to_proc
b = a.curry.curry[4]
b.class # => Fixnum
b # => 16
print 1.upto(5).map(&b)
# wrong argument type Fixnum (expected Proc) (TypeError)
立即查看文档 - curried proc
收到一些参数。如果提供了一个有效数量*的参数,它会将提供的参数传递给原始proc
,返回结果。
在您的代码中,当您执行a.curry
时,它会返回 curried proc 。为什么?因为您的方法f
有一个可选的和一个必需的参数,但您没有提供任何参数。现在你再次调用a.curry.curry[4]
,所以在前面的 curried proc 仍在等待至少一个参数,这次你使用curry[4]
给它。现在,使用proc
作为参数调用 curried 4, 2
对象,并将其评估为Fixnum
对象8
并分配给b
。 b不是proc对象,而是Fixnum
对象。
现在,1.upto(5).map(&b)
此处 - &b
表示您正在告知将proc
对象分配给b
转换为块。但否,b
未持有proc
个对象,而是Fixnum
对象8
。所以Ruby 抱怨给你。
此消息来自错误的参数类型Fixnum(预期Proc)(TypeError)。
现在来看你的第二部分代码。坚持,稍等!! : - )
看下面:
def f(x, y)
x**y
end
a = method(:f).to_proc
b = a.curry.curry[4]
b.class # => Proc
b # => #<Proc:0x87fbb6c (lambda)>
print 1.upto(5).map(&b)
# >> [4, 16, 64, 256, 1024]
现在,您的方法f
需要2个强制参数x, y
。 a.curry
,您没有通过任何内容,因此返回 curried proc 。再次a.curry.curry[4]
,哼哼你传递了一个必需的参数,即2中的4
。所以再次返回 curried proc 。
现在1.upto(5).map(&b)
,与之前的b
相同,需要proc
,并且您满足了它的需要,因为现在b是proc
个对象。 &b
将其转换为以下块:
1.upto(5).map { |num| b.call(num) }
又输出为 - [4, 16, 64, 256, 1024]
。
<强>摘要强>
现在假设您定义了proc
,如下所示:
p = Proc.new { |x, y, z = 2| x + y + z }
现在你要将p
作为 curried proc 。所以你做了p.curry
。请记住,在调用curry
时,您没有通过任何 arity 。现在点是一个 curried proc 将等待评估并返回x + y + z
的结果,除非并且直到你给它所需的所有必需参数来产生结果。
这意味着p.curry
会为您提供 curried proc 对象,如果您执行p.curry[1]
(意味着您现在将值传递给x
),那么得到了一个 curried proc 。现在,当您编写p.curry[1][2]
时,您传递的所有必需参数(意味着您现在将值传递给y
),因此现在将调用x + y + z
。
答案 1 :(得分:1)
您使用的是.map
,它需要block
类型proc
。在您的第一种情况下b
返回16
,y=2
在使用2
发送单个参数时使用默认值curry
作为指数。 b
返回16
不是proc
object
,不能与.map
一起使用。
Curry
与proc sufficient arguments
一起使用时,会执行原始proc并返回结果。在OP的第一个案例中发生了这种情况,curried proc传递了4作为唯一参数,默认y=2 in f(x, y=2)
被使用并导致16
作为返回值。 16 Fixnum
不能与枚举器map
方法一起使用。
Curry
使用参数不足时返回proc
。因此,在使用f(x, y)
的情况2中,curried a
仅传递一个参数,导致返回proc
对象{|e| 4 ** e}
,并由map
方法执行