foldrとfoldl

30分プログラム、その45。foldlとfoldrのPerlによる実装。

foldlとfoldr自体はもう何度も自分で書いているので、Perl再帰関数の書き方を覚える意味合いが強い。

use strict;
use warnings;
 
sub fact($){
    my ($i) = @_;
    if($i == 0){
	1;
    }else{
	$i * &fact($i-1);
    }
}
 
sub foldr(&$@){
    my ($f,$init,@list) = @_;
    unless(@list){
	$init;
    }else{
	my ($x,@xs) = @list;
	$f->($x,&foldr($f,$init,@xs));
    }
}
 
sub foldl(&$@){
    my ($f,$init,@list) = @_;
    unless(@list){
	$init;
    }else{
	my ($x,@xs) = @list;
	&foldl($f,$f->($x,$init),@xs);
    }
}
  • 関数内部ではまだプロトタイプ宣言が有効になっていないので、古いほうの呼び出し方で
  • Perlのファニー文字は実は、スカラーの$、配列の@、ハッシュの%、サブルーチンの&なのです

あとは、時間があまったので、代表的な再帰関数であるappendとlengthのPerl実装。

sub append(@){
    @_;
}

sub my_length(@){
    scalar @_;
}

いや、ネタですけどね。