Clojure 环路重现的改进
我编写了一个函数,它试图以交互方式从用户那里获得y/n(是/否)答案。它测试答案是否有效,如果无效,则再次请求用户:Clojure 环路重现的改进,clojure,Clojure,我编写了一个函数,它试图以交互方式从用户那里获得y/n(是/否)答案。它测试答案是否有效,如果无效,则再次请求用户: (defn get-valid-answer [question] (println question) (loop [] (let [ans (.trim (read-line))] (if (#{"y" "n"} ans) ans (do (println "Please answer \
(defn get-valid-answer [question]
(println question)
(loop []
(let [ans (.trim (read-line))]
(if (#{"y" "n"} ans)
ans
(do (println "Please answer \"y\"[yes] or \"n\"[no] only!")
(recur) )))))
上面的版本使用循环重现完成了这项工作,但我有一种烦人的感觉,那就是必须有一种更好的(功能更强大的)方法来完成这项工作。我宁愿只打一次电话。有人能推荐一个替代版本,在这种情况下不使用循环重现,但可能使用一些(Clojure内置)宏吗?想象一个小孩没完没了地问同样的问题,直到得到满意的回答,然后在代码中做同样的事情。也就是说,从层出不穷的问题中找出第一个有效的答案 未经测试,但这应该可以奏效
(defn ask []
(println "Please answer \"y\"[yes] or \"n\"[no]:")
(.trim (read-line)))
(defn get-valid-answer [question]
(println question)
(->> (repeatedly ask)
(filter #{"y" "n"})
(first)))
如果有两个函数困扰您,您还可以在
let
绑定中定义“ask”。这很好。我已经测试过它是否有效。但我对您的方法有一个问题:我看到“反复”进行惰性调用来询问,我认为惰性函数一次评估32个块,因此可能需要询问32个调用。通过我的测试,我可以看出这不会发生。“first”是否告诉Clojure重写32(thunk大小)并只调用一次来询问?如果您阅读LazySeq()的源代码,您可以看到项目一次评估一个。我看过你提到的帖子,但我不确定什么时候是真的,如果有的话。只有一些懒惰的序列被分块<代码>重复不是一个,但例如map
和range
是一个。还有更多。我找到了一个大块的seq?函数,对于range和map返回的惰性seq,仅当它们包装在seq中时才返回true,但如果重复使用,则始终会得到false: