2011-11-28
■ [再帰]"Deep recursion on anonymous subroutine"

合成関数を作る compose 関数を実装しようとして $f = sub { $f->($g->(@_)) } としたら、"Deep recursion on anonymous subroutine" と怒られた
use strict; use warnings; use feature qw(say); sub inc { my $x = shift; $x + 1; } sub double { my $x = shift; $x * 2; } sub square { my $x = shift; $x * $x; } sub compose { my $first = pop @_; while (my $g = pop @_) { # こうすると "Deep recursion on anonymous subroutine" と警告を出して無限ループしちゃう $first = sub { $first->($g->(@_)) }; } $first; } my $ids = compose(\&inc, \&double, \&square); my $sdi = compose(\&square, \&double, \&inc); say $ids->(3); say $sdi->(3);
なのでループの代わりに再帰させる
sub compose { my $f = pop @_; my $g; ($g = pop @_) ? compose(@_, sub { $f->($g->(@_)) }) : $f; } my $ids = compose(\&inc, \&double, \&square); my $sdi = compose(\&square, \&double, \&inc);
ただ、最初の compose もあっさり抜けられて
sub compose { my $first = pop @_; while (my $g = pop @_) { my $f = $first; # $f に代入するだけ $first = sub { $f->($g->(@_)) }; } $first; } my $ids = compose(\&inc, \&double, \&square); my $sdi = compose(\&square, \&double, \&inc); say $ids->(3); # 64 say $sdi->(3); # 19
焦ったのでメモ
コメントを書く
トラックバック - http://perl.g.hatena.ne.jp/ishiduca/20111128