如何结束dotimes clojure

时间:2018-12-02 11:43:03

标签: clojure

我试图猜测Clojure中的数字游戏,但我不断收到错误消息,说我只能从尾巴位置再次出现

(def n (rand-int 100))

(prn n)

(println "You have 10 guesses :D")
(println "HINT: My number is between 1 and 100")

(dotimes [i 10]
  (def guess (read-line))
  (if (= guess str(n))
    (recur (println "Correct!") (println "Incorrect"))))

(我是Clojure的新手)

3 个答案:

答案 0 :(得分:4)

dotimes用于执行主体以产生确切数量的副作用; break没有其他方法-除了扔

loop(或功能)是recur的目标。接下来,如果用户没有猜到,则您必须记下尝试的次数,以便您可以停止:

(loop [attempts 10]
  ; ...
  (recur (dec attempts)))

还有其他问题:

  • 请勿在其他表格中使用def。请改用let
  • str(n)将抛出,因为它将尝试调用nClassCastException java.lang.Long cannot be cast to clojure.lang.IFn
  • recurprintln的搭配看起来很糟糕,因为println总是返回nil

答案 1 :(得分:1)

您如何结束dotimes?你不知道尝试改用loop。您的代码有很多问题,但这只是一个开始。

答案 2 :(得分:0)

尽管不鼓励这样做并且反而以这种方式使执行短路,但使用宏仍然完全有可能(纯粹出于教育和娱乐目的)

(defmacro return [& x]
  `(list '~'return (do ~@x)))

(defmacro dotimes+ [[i n] & body]
  `(loop [~i 0 res# nil]
     (cond (and (list? res#) (= '~'return (first res#))) (second res#)
           (< ~i ~n) (recur (inc ~i) (do ~@body))
           :else res#)))

可以这样使用:

user> (dotimes+ [i 10]
        (println i)
        (if (== i 5) (return :short-circuited)))
;; 0
;; 1
;; 2
;; 3
;; 4
;; 5
:short-circuited

user> (dotimes+ [i 10]
        (println i)
        (if (== i 5) (return)))
;; 0
;; 1
;; 2
;; 3
;; 4
;; 5
nil

user> (dotimes+ [i 10]
        (println i))
;; 0
;; 1
;; 2
;; 3
;; 4
;; 5
;; 6
;; 7
;; 8
;; 9
nil

请注意,它仍然希望在结尾位置调用return宏(类似于recur宏中的loop

(dotimes+ [x 4]
  (println "attempt" (inc x))
  (let [answer (read-line)]
    (println "answer is:" answer)
      (if (= answer "yes")
        (return "YEAH!!!")
        (println "WRONG!"))))