作者godfat (godfat 真常)
看板Ruby
标题[心得] ludy 0.0.4 released
时间Mon Aug 13 00:55:10 2007
edited:
gem install ludy
to see detail.
花了一点时间再测试了一下 curry 的实做,
i am glad to announce that ludy 0.0.4 is released.
原本的 Proc#curry 被改名为 Proc
#__curry__, 我很想把他
deprecate 掉,但是後来的 Kernel#curry 也有运用到该实做,
是有在考虑把他从 public 改到 private, 但考虑到也许还有用处,
还是暂时放在 public 下,以後如果发现真的没用了,会改到 private 下。
现在的用法是:
multiply = lambda{|l,r| l*r}
double = multiply.curry[2]
assert_equal 8, double[4]
assert_equal 6, double[3]
xd = multiply['XD', 5]
assert_equal 'XDXDXDXDXD', xd
assert_equal 29, :+.to_proc.curry[18][11]
assert_equal (0..4).to_a, lambda{|a,b,c,d,e|[a,b,c,d,e]}.curry[0][1][2][3][4]
只要呼叫到了 Kernel#curry, 且 caller 本身回应(respond_to?)
:call 和 :[], 则回传一个 curry function, 这样就可以有更强的
consistency, 不需要注意什麽时候使用 () 而什麽时候使用 [],
请一律使用 function call/[], 不用担心参数是否足够,足够时就会
回传真正的答案,否则再度传回 curry function.
所以其实我是在想,以下两者是否相同?
class Array; include Curry; end
func1 = [].cfoldr
func2 = [].method(:foldr).curry
func1 == func2 # => true? or false?
我的希望是相同,当然。只是我直接换上这样的实做似乎有点问题,
这个状况可能在 0.0.5 中解决,使 curry module 和 kernel#curry
也能够拥有该有的一致性。
另一个棘手问题是 ruby 的 block, 乍看很好用,实际上也是,但是却
造成了很大的不一致。这一点也真的是很难搞定,之前的 this 就有碰上
这样的大问题,使用 yield 似乎无法产生正确的 call stack.
*
最後则是 0.0.4 上的实做问题,由於 :*.to_proc 的这个 proc 无法
预测其正确的 arity, 就像 :message_that_you_never_know.to_proc
也不可能能知道他的 arity 是多少一样,这造成了难以判断何时该回传
正确的值而非另一个 curry function. 我是想要从 Symbol#to_proc 去
窜改,不过这会碰上另外两个问题:
1. 会跟其他人的实做冲突
2. caller 和 arity 是合并在一起的,意味还没 call 之前都不会知道
arity, 这样我就没办法强迫 Symbol#to_proc 能产生正确的 arity.
所以我只好用另外一个很愚蠢的方式:trial & error.
begin # let's try if arguments are ready
self.__send__ :orig_call, *args, &block
rescue ArgumentError # oops, let's curry it
method(:call).to_proc.__send__ :__curry__, *args
end
效率问题就别提了,我真的觉得这样很蠢,可是好像也想不到更好的方式。
所以 0.0.4 就只暂时强化了 curry 的实做,离完善还有很大的一段距离。
虽然心血来潮度极高,但好像还算有进展?
--
By Gamers, For Gamers - from the past Interplay
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.135.28.18
※ 编辑: godfat 来自: 220.135.28.18 (08/13 01:04)