FizzBuzzにももうええかげん食傷してきたので、次のネタをないかと思ったら、yuguiさんがtwitterで私を登録したので、ごぶさた〜と思ってblogを見に行って格好の素材を(再)発見したという前回までのあらすじ。

inject + Symbol#to_proc = fold @ 2007年05月 @ ratio - rational - irrational @ IDM
(1..10).inject(&:*)
 =>  3628800
うーむ。素晴らしい。

reduce(l|r)

というわけで問題。reducelとreducerを実装せよ。制限時間はあわせて10分。ただし、reducelとreducerは、Haskellにおいて次の挙動を示すものとする。

*Main> reducel (\x y -> "("++x++"#"++y++")") $ map show [1..4]
"(((1#2)#3)#4)"
*Main> reducer (\x y -> "("++x++"#"++y++")") $ map show [1..4]
"(1#(2#(3#4)))"

Perl 5による回答例

sub reducel(&@){
    my $binop = shift;
    my $result = shift;
    $result = $binop->($result, shift) while(@_);
    $result;
}

sub reducer(&@){
    my $binop = shift;
    my $result = pop;
    $result = $binop->(pop, $result) while(@_);
    $result;

}
$\="\n";
print reducel { "($_[0]#$_[1])" } (1..4); # (((1#2)#3)#4)
print reducer { "($_[0]#$_[1])" } (1..4); # (1#(2#(3#4)))

Extra Credit

Haskellのfold(l|r)は、なぜfoldx binop [...]ではなくfoldx binop init [...]という具合に初期値を必要とするのか、その理由を述べよ。

Dan the (Dys)?functional

追記: Twitterで私を友人登録して下さったみなさん、私が友人登録しないからといって嘆かないで下さいネ。私は猫をいぢめたくないだけなので。