Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 环路重现的改进_Clojure - Fatal编程技术网

Clojure 环路重现的改进

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 \

我编写了一个函数,它试图以交互方式从用户那里获得y/n(是/否)答案。它测试答案是否有效,如果无效,则再次请求用户:

(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: