カリー関数

関数を返す関数(高階関数)を作ってみます。お題は、関数の引数を束縛する(カリー化する)関数です。

# curry.pl
 
sub curry {
	my $func = shift;
	my @arg = @_;
	return sub { return $func->(@arg, @_); }
}
 
 
my $printer = sub { print "@_\n"; };
$printer->("I", "am", "a", "printer!");
 
my $hello_printer = curry($printer, "Hello,");
$hello_printer->("world!");
$hello_printer->("perl!");
 
my $introduce = curry($printer, "My", "name", "is");
$introduce->("palmo");
 
 
my $multiply = sub {
	$answer = 1;
	for (@_) { $answer *= $_; }
	return $answer;
};
print $multiply->(2, 3, 4), "\n";
 
my $ten_times = curry($multiply, 10);
print $ten_times->(5), "\n";

関数 curry に、関数と束縛したい引数を渡すと、カリー化された関数が返ってきます。
引数を print する $printer の第一引数を "Hello," で束縛したのが $hello_printer です。関数が返されていますね。複数の引数を束縛できるようにしたので、$introduce で試してみました。
$multiply は与えた引数を全て掛け合わせた答えを返します。$ten_times は $multiply の第一引数を 10 で束縛したものです。
実行結果です。

I am a printer!
Hello, world!
Hello, perl!
My name is palmo
24
50

無名関数はとても面白くて便利なのですが、多用すると読みづらくなってしまうので、注意しなくてはいけませんね。