3

recurはテール位置にしか存在できないため、現在エラーが発生しているコードがいくつかあります。関数は次のとおりです。

(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))))

これを修正するために考えることができる1つの方法は、条件付きバインディングです 。countがゼロ未満の場合は、count-operatorを「inc」に設定します。それ以外の場合は「dec」に設定し、最後に繰り返します。

その後、これは私の問題を修正します。しかし、clojureでこれを行う方法がわかりません。または、それが可能である場合でも、when-letおよびif-letがこれを行わないようです。1回の繰り返しのみを使用するようにコードを修正する最良の方法は何ですか?

編集:私がここで学んだいくつかのこと:

1)ループステートメントがない場合、「recur」はdefnに戻ります。私が読んだ本では、recurの例はすべてloop / recurを使用しているので、ループが必要だと思いました。そうではありません、私のループステートメントは不要です。

2)括弧を間違えると、紛らわしいエラーが発生しました。両方のcondステートメントが相互に排他的であるため、末尾にあるとは見なされないのは奇妙なことでした。私のパレン完了チェッカーにもう少し注意を払うべきでした。

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

4

2 に答える 2

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を使用しました)。

複数のsに問題はありrecurません。末尾再帰は、テキストの最後の行にある必要があることを意味するのではなく、戻ったときに計算を行う必要がないことだけを意味します。

主な問題は、parensの混乱でした(後に多すぎますcount)。自動インデントする(そして自動インデントを執拗に使用する)エディターを入手することをお勧めします。それはすぐにparensの問題を示したでしょう(私はintellijのアイデアでlaclojureプラグインを使用していますが、他の人も同様の機能を持っていると確信しています)。

更新:なぜloop必要なのですか?

(defn foo [scale degree]
  (cond 
    (zero? degree) scale 
    (< degree 0) (recur (step (reverse scale)) (inc degree))
    :else (recur (step scale) (dec degree))))
于 2012-05-09T01:20:27.903 に答える
3

元の質問で、「これを修正するために考えられる1つの方法は、条件付きバインディングです。カウントがゼロ未満の場合は、count-operatorを「inc」に設定します。それ以外の場合は「dec」に設定してから繰り返します。最後に。" そして誰もその部分に答えませんでした:

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

ある場合にはreverseを呼び出し、他の場合には呼び出さないことを除いて、そのための条件付きバインディングも必要です。両方をデストラクチャリングを使用してバインドする例を次に示します。

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

Andrew Cookeが指摘したように、各「テール」に繰り返しがある(ループがない)単純な条件は問題なく機能します。

于 2012-05-09T02:12:39.680 に答える