Una Función curry

El siguiente ejemplo muestra una función curry que recibe como argumento una función

$\displaystyle f : D_1 \times \ldots \times D_{n} \rightarrow E$    

y retorna una función que currifica esa función:

$\displaystyle curry(f) : D_1 \rightarrow \mathcal{F}(D_2 \times \ldots \times D_n, E)$    

donde $ \mathcal{F}(D_2 \times \ldots \times D_n, E)$ denota las funciones con argumentos en $ D_2 \times \ldots \times D_n$ y valores en $ E$ .

Cuando a la función $ curry(f)$ se le pasa un argumento adicional $ x$ se obtiene una nueva función:

$\displaystyle curry(f)(x) : D_2 \times \ldots \times D_n \rightarrow E$    

Sigue un ejemplo de uso:

15  die "Error\n" unless @ARGV;
16  my $cprod = curry(sub { $_[0]*$_[1] });
17  my $doble = $cprod->(2);
18  my @dobles = map { $doble->($_) } @ARGV;
19  print "@dobles\n";
20
21  my $cfirst = curry(\&first);
22  my $fodd = $cfirst->( sub { $_ % 2 } ); # Primer impar
23  print $fodd->(@ARGV)."\n";
lhp@nereida:~/Lperl/src$ currying2.pl 4 8 12 9 23 25
8 16 24 18 46 50
9

Veamos el código y una ejecución:

lhp@nereida:~/Lperl/src$ cat -n currying2.pl
 1  #!/usr/bin/perl -w
 2  use strict;
 3  use List::Util qw(first);
 4
 5  sub curry {
 6    my $f = shift; # Referencia a una función de dos o mas argumentos
 7
 8    return sub {  # Retorna función como f pero con un arg. menos
 9      my $x = shift;
10      my $fx = sub { $f->($x, @_) };
11      return $fx;
12    };
13  }

La técnica de currificación transforma una función ordinaria en una fábrica de funciones (function factory). Al llamar a la fábrica con un parámetro nos devuelve una nueva función.

Ejercicio 4.18.3   ¿Que describe la expresión curry(\&List::Util::sum)->(4)->(1..5)? Si tiene dudas lea la siguiente sesión con el depurador:
lhp@nereida:~/Lperl/src$ perl -wd currying2.pl
main::(currying2.pl:15):        die "Error\n" unless @ARGV;
  DB<1>  $f = \&List::Util::sum
  DB<2> $g = curry($f)
  DB<3> $h = $g->(4)
  DB<4> x $h->(1..5)
0  19

Casiano Rodríguez León
Licencia de Creative Commons
Principios de Programación Imperativa, Funcional y Orientada a Objetos Una Introducción en Perl/Una Introducción a Perl
por Casiano Rodríguez León is licensed under a Creative Commons Reconocimiento 3.0 Unported License.

Permissions beyond the scope of this license may be available at http://campusvirtual.ull.es/ocw/course/view.php?id=43.
2012-06-19