2012-07-25 11 views
5

Escribí una función que intenta obtener una respuesta y/n (sí/no) de un usuario de forma interactiva. Pone a prueba si la respuesta es válida y si no es así, solicita al usuario una vez más:Mejorando en recurrencia de bucle

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

La versión anterior con bucle se repiten hace el trabajo pero no tengo sensación de que tiene que haber una manera mejor (más funcional) a hacer esto. Preferiría tener la llamada de línea de lectura hecha solo una vez. ¿Podría alguien sugerir una versión alternativa que no utiliza loop-recur en este escenario, pero que posiblemente utiliza alguna macro (Clojure builtin) en su lugar?

Respuesta

7

Piense en un niño pequeño que hace la misma pregunta interminablemente hasta que obtenga una respuesta satisfactoria, luego haga lo mismo en el código. Es decir, tome la primera respuesta válida de un flujo interminable de preguntas.

No probado, pero esto debería hacer el truco.

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

También podría definir 'pedir' en un let de unión, si dos funciones le molesta.

+0

Eso está bien. He probado que funciona. Pero tengo una pregunta sobre su enfoque: veo que 'repetidamente' hace llamadas flojas para preguntar y pensé que las funciones perezosas evalúan fragmentos de 32 a la vez, de modo que puede haber 32 invocaciones para preguntar. Según mi prueba, puedo ver que eso no sucede. ¿El "primero" le dice a Clojure que sobrescriba el 32 (tamaño de procesador) y hace solo una invocación para preguntar? – Don

+0

Si lee la fuente de LazySeq (https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LazySeq.java), puede ver por sí mismo que los elementos se evalúan uno a hora. He visto la publicación a la que te refieres, pero no estoy seguro de si eso fue cierto, si es que alguna vez lo hizo. – Ben

+0

Gracias por el seguimiento. – Don

Cuestiones relacionadas