実装すた!

reduce(l|r)

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

Symbol.class_eval do
	def to_proc
		proc do
			|*x|
			obj = x.shift
			obj.__send__(self, *x)
		end
	end
end

Enumerable.module_eval do
#	def reducel
#		self.inject {|r, v| yield(r, v) }
	def reducel (&block)
		self.inject(&block)
	end

	def reducer (&block)
		self.to_a.reverse.inject {|r, v| yield(v, r) }
	end
end

puts (1..4).reducel {|x, y| "(#{x}##{y})" }
puts (1..4).reducer {|x, y| "(#{x}##{y})" }

puts (1..10).reducer {|x, y| x * y }
puts (1..10).reducel {|x, y| x * y }
puts (1..10).inject(&:*)

あれれー

なんで、module_eval とかつかってるんだろ。

ぬぐ

なんかだめな感じなのでちょびってかえた。
脳がくさってる証拠だ。

xtal

http://d.hatena.ne.jp/xtalco/
http://code.google.com/p/xtal-language/
injectは何か定義済みっぽいけれど、謎だったので ingect なるものをでっちあげた。

lib::builtin::Iterator::ingect : method (f) {
	result : nop;
	this.with_index {
		|idx, it|
		if (idx == 0) {
			result = it;
		} else {
			result = f(result, it);
		}
	}
	return result;
}
lib::builtin::Iterator::reverse : method () {
	return fiber () {
		ary : this.to_a;
		for (i : ary.size - 1; i >= 0; i--) {
			yield(ary[i]);
		}
	}
}

lib::builtin::Iterator::reducel : method (f) {
//	return this.ingect(|r, v| f(r, v));
	return this.ingect(f);
}

lib::builtin::Iterator::reducer : method (f) {
	return this.reverse.ingect(flip(f));
}

//f : fun (x, y) { return "(" ~ x.to_s ~ "#" ~ y.to_s ~ ")"; }
f : %f[(%s#%s)];
range(1, 4 + 1).reducel(f).p;
range(1, 4 + 1).reducer(f).p;

ぬううん

neko : range(1, 2);
neko { it.p; }
neko { it.p; }

これやると一個しか数字出力されないのでなんでだろー

バグだった

http://d.hatena.ne.jp/xtalco/20070529
お返事感謝。

to_proc 071009

引数の数が自由になるように修正