ruby-1.9.2-head :013 > product = lambda { |x, y| x * y } # A function of two arguments => #<Proc:0x007fbf53991668@(irb):13 (lambda)> ruby-1.9.2-head :014 > double = lambda { |y| product[2, y] } # Fix one argument, vary the other => #<Proc:0x007fbf530a9de8@(irb):14 (lambda)> ruby-1.9.2-head :015 > double[4] => 8
En esta sección extendemos el módulo Functional
con dos operaciones
lambda >> expresion
retorna una lambda
en la que se ha fijado el primer
argumento a expression
lambda << expresion
retorna una lambda
en la que se ha fijado el último
argumento a expression
if __FILE__ == $0 p = lambda {|x,y,z| x*y-z} d = p >> 2 >> 3 # x = 2 y = 3 puts d[1] # 5 = 2*3-1 f = p << 4 << 5 # z = 4 y = 5 puts f[2] # 6 = 2*5-4 endImplementación:
[~/TheRubyProgrammingLanguage/Chapter6MethodsProcsLambdasAndClosures]$ cat functional_partial.rb require "./functional_compose" module Functional def apply_head(*first) lambda {|*rest| self[*first.concat(rest)]} end def apply_tail(*last) lambda {|*rest| self[*rest.concat(last)]} end alias >> apply_head # g = f >> 2 -- set first arg to 2 alias << apply_tail # g = f << 2 -- set last arg to 2 end
En Ruby 1.9 la clase Proc dispone del método curry. El método retorna un curried proc. Un curried proc si no recibe suficientes argumentos retorna un proc parcial sobre el resto de los argumentos:
ruby-1.9.2-head :006 > b = proc {|x, y, z| x+2*y-z } => #<Proc:0x007fac98842cd0@(irb):6> ruby-1.9.2-head :007 > c = b.curry => #<Proc:0x007fac88828278> ruby-1.9.2-head :009 > c[1,2,3] => 2 ruby-1.9.2-head :010 > c[1,2] => #<Proc:0x007fac88913688> ruby-1.9.2-head :011 > c[1,2][3] => 2
Functional
de manera que el operador **
admita como segundo argumento
un objeto hash cuyas claves son las posiciones de los argumentos que se desean fijar y cuyos valores indican
las expresiones a las que deben ser fijadas:
p = lambda {|x,y,z,w=0| x*y-z+w } d = p ** {0 => 1, 2 => 3} # x = 1 z = 3 puts d[4] # 1 = 1*4-3+0
Casiano Rodriguez León 2015-01-07