Skip to content

Instantly share code, notes, and snippets.

@ishiduca
Created December 6, 2011 12:23
Show Gist options
  • Save ishiduca/1438022 to your computer and use it in GitHub Desktop.
Save ishiduca/1438022 to your computer and use it in GitHub Desktop.
自前 fold & foldr で合成関数
#!/usr/bin/env perl -l
use strict;
use warnings;
use Data::Dumper;
sub fold {
my $f = shift;
my $res = shift;
my @rest = @_;
ref $f ne 'CODE' and die qq(first argument should be 'code ref');
while (my $first = shift @rest) {
$res = $f->($res, $first);
}
$res;
}
sub foldr {
my $f = shift;
fold($f, reverse @_);
}
# case 1: eq reduce{ $a + $b }@nums;
my @nums = (1, 2, 3, 4);
print fold(sub { $_[0] + $_[1] } , @nums); # 10
# case 2: eq reduce{ [ @$a, @$b ] }@arrays;
my @arrays = ([ 1, 2 ], [ 3, 4 ], [ 5, 6 ]);
print Dumper fold(sub { [ @{$_[0]}, @{$_[1]} ] }, @arrays);
# [ 1, 2, 3, 4, 5, 6 ]
sub inc {
my $n = shift;
$n + 1;
}
sub double {
my $n = shift;
$n * 2;
}
sub square {
my $n = shift;
$n * $n;
}
sub fg {
my($f, $g) = @_;
sub { $f->($g->(@_)) };
}
# case 3
my $func = foldr(\&fg, \&inc, \&double, \&square);
print $func->(3); # 64; ((3+1) * 2) ^ 2
__END__
@ishiduca
Copy link
Author

ishiduca commented Dec 7, 2011

sub fg {
    foldr(sub {
        my($f, $g) = @_;
        sub { $f->($g->(@_)) };
    }, @_);
}

my $func = fg(\&inc, \&double, \&square);
print $func->(3);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment