我试图猜测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的新手)
答案 0 :(得分:4)
dotimes
用于执行主体以产生确切数量的副作用; break
没有其他方法-除了扔
loop
(或功能)是recur
的目标。接下来,如果用户没有猜到,则您必须记下尝试的次数,以便您可以停止:
(loop [attempts 10]
; ...
(recur (dec attempts)))
还有其他问题:
def
。请改用let
。str(n)
将抛出,因为它将尝试调用n
(ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn
)recur
与println
的搭配看起来很糟糕,因为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!"))))