つづき
(m-n)%3 をどうやって計算するか?
(m-n)%3 = (m+n+n)%3 を使うと引き算がいらなくなる。
let.m_n_mod3 = abs m, n do add(m, add(n, n)) end
あとは、トリプルからk%3番目をとってくる関数を実装すればできあがりだ。
それは、k回トリプルをシフトして、最初のをとってくればよい。
トリプルをシフトするのは
let.shift = abs a, b, c, f do f(b, c, a) end let.tr1_s = tr1(shift) let.tr1_ss = tr1(shift, shift)
というようにすればよい。よって
let.exec_tr = abs tr, k do let.tr_k = tr(shift, shift, ... (k times) ..., shift) let.f = tr(get_1st) f(f) end
な感じになるのだが、数値はここの繰り返しにしか使わないので、
最初から、shiftを何回繰り返したかを数値の表現に使えばいいことがわかる。
shiftを一回合成する関数は
let.add_shift = abs shifts, a, b, c do shifts(b, c, a) end let.shift_2 = add_shift(shift) let.shift_3 = add_shift(add_shift(shift))
である。
というわけで、m_n_mod3はもういらなくなって
let.exec_tr = abs tr, m, n do tr(m, n, n, apply_2nd_3rd) end
ときれいにかけるわけだ。