On Feb 16, 7:48 am, Trans <transf... / gmail.com> wrote: > On Feb 15, 8:10 pm, "Brian Mitchell" <binar... / gmail.com> wrote: > > > > > On Fri, Feb 15, 2008 at 5:06 PM, Trans <transf... / gmail.com> wrote: > > > > On Feb 15, 12:46 pm, Yukihiro Matsumoto <m... / ruby-lang.org> wrote: > > > > Hi, > > > > > In message "Re: Proc#curry" > > > > > on Sat, 16 Feb 2008 02:35:23 +0900, Trans <transf... / gmail.com> writes: > > > > > |Is there a link where I can read about how this new function works? > > > > > [ruby-dev:33676], if you don't mind seeing Japanese ;-) > > > > > If you do mind, it's OK. It's not difficult at all, > > > > > proc {|x, y, z| x + y + z }.curry > > > > > returns the proc object equivalent to > > > > > proc {|x| proc {|y| proc {|z| x + y + z } } } > > > > > See? > > > > Yep. I see. > > > > It is rather trivial, I agree. Unfortunately maybe too trivial because > > > were stuck with the order of arguments. Or doe curry take some > > > argument to vary that? To clarify what I mean, Facets has an > > > implementation of curry, for both Proc and Method, like so: > > > > proc {|x, y, z| x + y + z }.curry(__,__,__) > > > > Of course I like your better in this case ;-) BUT, it does allow: > > > > proc {|x, y, z| x + y + z }.curry(__,5,__) > > > > for: > > > > proc {|x| proc {|z| x + 5 + z } } > > > Isn't that partial application not currying per say (one could curry > > as a way to implement partial application)? > > I've also heard it called "partial currying". I'd rather have a > superset of funtionality then a subset. Currying is about isolating a > single argument. It doesn't dictate in which argument to isolate. It > could be x, y, or z, etc. Nor does it mean currying every variable all > the way down that line. > > If we give matz's curry function an arity-slot number as an optional > argument, then we could do it all like so: > > P = proc { |x,y,z| x+y+z } > P.curry(1) => proc { |y| proc |x,z| x+y+z } } > > Which would then allow partial applicaiton via: > > P.curry(1)[5] > > A second argument could dictate the next level of currying > > P.curry(1,1) => proc { |y| proc |z| proc |x| x+y+z } } Here is an example implementation: class Proc def curry(*args) if args.empty? idx = (0...arity).to_a else raise ArgumentError, "argument count is greater than arity (#{args.size} > #{arity})" if args.size > arity raise ArgumentError, "arguments must be unique indexes" if args.uniq != args raise ArgumentError, "arguments must be indexes" if args.any? { |a| !Fixnum===a } idx = (0...arity).to_a idx = args + (idx - args) end rec = '' idx.each do |i| rec << "proc { |a#{i}| " end rec << "self[" rec << (0...arity).to_a.collect{|i| "a#{i}"}.join(',') rec << "]" rec << "}" * arity instance_eval rec end end Example: >> a = proc { |x,y| x**y } => #<Proc:0x00002aae4fd50638@(irb):5> >> b = a.curry(0) => #<Proc:0x00002aae4fd4b110@(eval):1> >> c = a.curry(1) => #<Proc:0x00002aae4fd45aa8@(eval):1> >> b[2][3] => 8 >> c[2][3] => 9 I'd appreciate suggestions for improvement, as I certainly expect there are a plenty. T.