gpt4 book ai didi

ruby - 为什么 Ruby 中的柯里化(Currying)在我的代码中不起作用?

转载 作者:数据小太阳 更新时间:2023-10-29 08:27:20 27 4
gpt4 key购买 nike

我在尝试运行以下脚本时收到错误消息“method_object.rb:8:in `': 错误的参数类型 Fixnum (expected 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

谁能帮我解决我的第一个代码出现的问题?

最佳答案

Proc#curry

Returns a curried proc. If the optional arity argument is given, it determines the number of arguments. A curried proc receives some arguments. If a sufficient number of arguments are supplied, it passes the supplied arguments to the original proc and returns the result. Otherwise, returns another curried proc that takes the rest of arguments.

现在开始你的代码:

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]。现在 curried proc 对象以 4, 2 作为参数被调用,并评估为 Fixnum 对象 8 并分配给 bb 不是 proc 对象,而是 Fixnum 对象。

现在,1.upto(5).map(&b) 这里 - &b 意味着,你告诉转换 proc 对象b 到一个 block 。但是NOb 没有保存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, ya.curry,您没有传递任何内容,因此返回了一个curried proc。再次 a.curry.curry[4],嗯,你传递了一个必需的参数,它是 4 out of 2。所以又是一个 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 将被调用。

关于ruby - 为什么 Ruby 中的柯里化(Currying)在我的代码中不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22750467/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com