Composición de Funciones

En esta sección ampliamos el módulo Functional con el operador * para denotar la composición de procs, lambdas y methods. De esta forma, el anterior ejemplo puede reescribirse de este modo:

if __FILE__ == $0
  def polar(x,y)
    [Math.hypot(y,x), Math.atan2(y,x)]
  end
  def cartesian(magnitude, angle)
    [magnitude*Math.cos(angle), magnitude*Math.sin(angle)]
  end

  f = lambda {|x| x*x }
  g = lambda {|x| x+1 }
  puts (f*g)[2]   # => 9
  puts (g*f)[2]   # => 5
  
  p,c = method(:polar), method(:cartesian)
  puts (c*p)[3,4]  # => [3,4]
  
  a = (1..5).to_a
  sum = lambda {|x,y| x+y }        # A function to add two numbers
  mean = (sum<=a)/a.size           # Or sum.reduce(a) or a.inject(&sum)
  deviation = lambda {|x| x-mean } # Function to compute difference from mean
  square = lambda {|x| x*x }       # Function to square a number
  puts sum<=square*deviation|a     # 10 = 4 + 1 + 4 + 1
  standardDeviation = Math.sqrt((sum<=square*deviation|a)/(a.size-1).to_f)
  puts standardDeviation           # sqrt(10/4) = 1.5811388300841898
end

~/TheRubyProgrammingLanguage/Chapter6MethodsProcsLambdasAndClosures]$ cat functional_compose.rb 
require './functional'

module Functional
  def compose(f)
    if self.respond_to?(:arity) && self.arity == 1
      lambda {|*args| self[f[*args]] }
    else
      lambda {|*args| self[*f[*args]] }
    end
  end

  alias * compose
end



Casiano Rodriguez León 2015-01-07