#! perl -l
my $f = sub { "f($_[0])" };
my $g = sub { "g($_[0])" };
print $f->("x");
# f(x)
print $g->("x");
# g(x)
####
sub compose2 {
my ($f, $g) = @_;
sub { $f->( $g->(@_) ) }
}
####
my $h = compose2( $f, $g );
print $h->("x");
# f(g(x))
####
sub foldl {
my $f = shift;
my $z = shift;
$z = $f->($z, $_) for @_;
$z;
}
sub compose {
foldl( \&compose2, @_ )
}
####
print compose( $f,$f,$f,$f,$f,$f,$g )->("x");
# f(f(f(f(f(f(g(x)))))))
my $add1 = sub { $_[0] + 1 };
my $add2 = compose( $add1, $add1 );
my $add4 = compose( $add2, $add2 );
print $add2->(0);
# 2
print $add4->(0);
# 4
print compose( $add1, $add1, $add1 )->(0);
# 3
print compose( ($add1) x 4 )->(0);
# 4