2012-05-09 3 views
3

私は現在、エラーが発生しているコードをいくつか持っています。なぜなら、再発は末尾にしかないからです。ここでの機能があります:私は言うことができれば、私はこの問題を解決するために考えることができますclojure:末尾にrecurを配置するcondでバインディングを使用しますか?

(defmethod transposer 
    Long [scale degree] 
    (loop [new-scale scale count degree] 
    (cond 
     (zero? count) new-scale 
     (< count 0) (recur (step (reverse new-scale)) (inc count))) 
     :else (recur (step new-scale) (dec count)))) 

一つの方法は、結合条件付きである: カウントがゼロより小さいとき、「それ以外に設定し、「株式会社」へのオペレータをカウント設定しましたdec "にして、最後に再発する。

これで問題が解決します。しかし、私はクローゼットでこれをどうやって行うのか、あるいはそれが可能なのかどうかは分かりません。 1つの反復だけを使用するようにコードを修正する最良の方法は何ですか?

編集:私は、ここで学んだことのカップル:

1)はループ文はありません場合は、バックDEFNに再発する「再発」。私が読んだ本では、繰り返し使用のすべての例はループ/再帰を使用するので、ループを持つ必要があると考えました。そうではありません、私のループステートメントは不必要です。

2)かっこを誤って入力すると、混乱するエラーが発生しました。両方のcond文が互いに排他的であるため、両方のcond文が末尾にあるとは思われません。私はparen完了チェッカーにもう少し注意を払う必要がありました。

3)条件付きバインディングを実行したい場合は、標準の「let」ステートメントを使用して、そこに条件付きロジックを含めることができます。 Javaの背景から来て、私は時々、この領域で許容される柔軟性を忘れる。

+1

あなたのコードを理解できません。 'loop'の中の' recur'はループを呼び出しますが、あなたのargsリストは一致しません。何のために '' do? –

+1

最後の行にあるはずの2行目から最後の行に余分な括弧もあります。 – Jeremy

+0

申し訳ありませんが、私がやっていたデバッグから "do"が残っていました。私はそれを削除しました。 –

答えて

4
(defn foo [scale degree] 
    (loop [new-scale scale count degree] 
    (cond 
     (zero? count) new-scale 
     (< count 0) (recur (step (reverse new-scale)) (inc count)) 
     :else (recur (step new-scale) (dec count))))) 

は、あなたが、私は考えて欲しいものに近い(それは尾のエラーを与えるものではありません。私はスタンドアロンをテストするために、単純DEFN使用しました)。

複数の問題はありませんrecur s - tail再帰は、テキストの最後の行になければならないということを意味するものではありません。

主な問題は迷子になりました(countの後に多すぎます)。私は、自動インデント(および自動インデントを執筆して使用する)を取得することをお勧めします。それはすぐにparensの問題を示していたでしょう(私はintelijのアイデアでla clojureプラグインを使用しますが、他の人が同様の機能を持っていると確信しています)。

更新:なぜloopが必要なのですか?あなたの元の質問に

(defn foo [scale degree] 
    (cond 
    (zero? degree) scale 
    (< degree 0) (recur (step (reverse scale)) (inc degree)) 
    :else (recur (step scale) (dec degree)))) 
+0

hmmm、私は反復引数が間違っているとは思わない、新しいスケールとカウントの2つの値があるはずです。 「スケール」と「度」はその初期値です。どちらの再帰文も2つのパラメータを渡します。私は何かを欠いている? –

+0

ああ、申し訳ありませんが、あなたは正しいです。私は自分自身をあまり使っていません。更新しました。 –

+0

ですが、その場合、なぜloop?!?! –

3

、あなたは「私が言うことができる場合、私はこの問題を解決するために考えることができる一つの方法は、結合条件付きである:カウントがゼロよりも小さい場合にカウント演算子を設定し、 『尋ねINC』、それ以外の場合は設定"dec"にして、最後に再発する。 "そして誰もその部分に答えない:

(let [d (if (neg? degree) inc dec)] 
    (recur (step scale) (d degree))) 

あなたはあまりにもそのための条件付きの結合を必要とするので、他の1の場合には逆に電話しないようにしたいことを除いて。ここでは両方使用して非構造を結合例を示します。

(let [[s d] (if (neg? degree) [reverse inc] [identity dec])] 
    (recur (step (s scale)) (d degree))) 

アンドリュー・クックが指摘したように、各「尾部」(なしループ)で再発を持つシンプルなcondがうまく動作しますが

+0

あなたの例を見れば、letの中にifを含めることができたのは明らかですが、それは私には起こりませんでした。ありがとう! –

関連する問題