在Clojure中退出Recur Loop

use*_*240 2 recursion loops tail-recursion clojure

我想要突破下面的循环,并在第10行评估为真时返回最佳最小值.我用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)))))))
Run Code Online (Sandbox Code Playgroud)

Thu*_*ail 6

关于 loop

  • 这不是loop循环:它是recur.
  • loop是一个let形成一个recur点.
  • 你没有也不能摆脱循环:把recur你打成一个.

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

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

......相当于

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

由于性能的某些损失,loop本来可以写成执行上述转换的宏.


至于你的代码:

这里有六个未定义的函数.为了清除编译,我们

(declare best-min-score 
         best-max-move
         best-min-move
         best-max-move
         make-move-on
         remaining-scores)
Run Code Online (Sandbox Code Playgroud)

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

  • 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)))))
Run Code Online (Sandbox Code Playgroud)

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