在Clojure中退出Recur Loop

时间:2014-10-16 19:07:07

标签: loops recursion clojure tail-recursion

我想突破下面的循环,并在第10行评估为true时返回最佳最小值。我用print语句查看了输出,当第10行评估为true时,它找到了我正在寻找的数据但仍在继续重复。在Clojure中有一种方法可以在语句求值为true时停止循环吗?或者我应该使用除循环之外的其他东西吗?

(defn minimax [board max-mark min-mark depth best-score] 
  (loop [board board
     max-mark max-mark
     min-mark min-mark
     depth depth
     best-score best-score]
  (if (= best-score (best-min-score board max-mark min-mark depth))
   (best-max-move board max-mark min-mark depth)                     
   (do                                                               
      (if (= best-score (best-min-score board min-mark max-mark depth))
       (best-min-move board min-mark max-mark depth)              
       (recur 
         (b/make-move-on board (remaining-scores board max-mark min-mark depth) max-mark)                
           min-mark 
           max-mark 
           (inc depth) 
           (dec best-score)))))))

1 个答案:

答案 0 :(得分:6)

关于loop

  • 不是loop循环:它是recur
  • looplet,形成recur点。
  • 你没有,并且无法摆脱循环recur将你分成一个。

loop相当于设置和调用匿名函数。例如

(loop [n 5, s "Hello, world!"]
  (if (zero? n)
    (first s)
    (recur (dec n) (rest s))))

......相当于

((fn [n s]
  (if (zero? n)
    (first s)
    (recur (dec n) (rest s))))
 5 "Hello, world!")

由于性能下降,loop可能已被写为执行上述转换的宏。


至于你的代码:

这里有六个未定义的功能。为了清除编译,我们

(declare best-min-score 
         best-max-move
         best-min-move
         best-max-move
         make-move-on
         remaining-scores)

还有两种冗余形式。这些没有主动伤害,但会使代码模糊不清。

  • 不需要loop:函数本身是合适的 recur的目标。
  • do什么都不做:它包含一个表格。

您的功能缩减为

(defn minimax [board max-mark min-mark depth best-score] 
  (if (= best-score (best-min-score board max-mark min-mark depth))
    (best-max-move board max-mark min-mark depth)
    (if (= best-score (best-min-score board min-mark max-mark depth))
      (best-min-move board min-mark max-mark depth)              
      (recur 
       (make-move-on board (remaining-scores board max-mark min-mark depth) max-mark)                
       min-mark 
       max-mark 
       (inc depth) 
       (dec best-score)))))

虽然任何未定义的函数可能会重复出现,但最好的选择是best-min-move