例えば, even/oddならこんな感じ.
(defn even-odd? [even-or-odd n] (loop [status even-or-odd n n] (cond (= status :even) (if (= n 0) true (recur :odd (dec n))) (= status :odd) (if (= n 0) false (recur :even (dec n))))))こう書いておいて,
user> (even-odd? :odd 9)と呼び出すとか. cond節が冗長になりますが, declare, defnと書いて, 無名関数で囲って, trampolineで待ち受けさせるのと大差ないかなと....思ったのですが, 比べてみると, やっぱり読みにくい. trampoline版のほうがシンプルですね.
(declare my-odd?) (defn my-even? [n] (if (= n 0) true #(my-odd? (dec n)))) (defn my-odd? [n] (if (= n 0) false #(my-even? (dec n))))適当に測ってみると少し早くなった程度.
user> (time (trampoline my-even? 10000000)) "Elapsed time: 2127.23756 msecs" true user> (time (even-odd? :even 10000000)) "Elapsed time: 1781.678006 msecs" trueしかし, 相互再帰を書く時の選択肢としてはありかなと思ったりしてます.
0 件のコメント :
コメントを投稿