使用嵌套输入,但不展平它

时间:2018-09-29 14:23:53

标签: recursion clojure

我有一个函数可以简化诸如:

(or x false) => x

然后,函数定义将未求值的表达式作为其参数。 我现在想像这样嵌套我的输入:

(or x (and true))

在任何地方我都能看到有关展平嵌套输入的文章,但是在这种情况下,由于每个列表的开头都使用逻辑运算符,因此该方法不起作用,因此必须首先处理最里面的列表,并将结果发送到下一个外部列表作为参数。

我知道我需要用最里面的列表的结果在自己的函数体中调用我的函数,直到到达最外面的列表,但是我不确定该怎么做或在Clojure中研究什么方法对此。

1 个答案:

答案 0 :(得分:2)

您所描述的几乎完全是clojure :-)中的表达式评估的语义,因此简短的答案是运行代码:-D,尽管我怀疑您正在寻找一个更有趣的答案。

这是一个简单的递归版本,适用于

  1. 递归地简化每个嵌套表达式
  2. 将简化规则应用于现有表达式

例如,这使用了一个过于简单的规则:

user> (defn my-eval [e]      
        (let [expanded-form (if (seq? e)
                              (map (fn [i]          
                                     (if (seq? i)    ;; if this is a sequence, 
                                       (my-eval i) ;; eval the sequence and include the result here
                                       i))         ;; otherwise use the value unchanged.
                                   e)
                              e)] ;; if it's not a seq with something in it, leve it unchanged
          (if (and
               (seq? expanded-form)
               (= (first expanded-form) 'or)
               (= 2 (count (remove false? expanded-form))))
            (second (remove false? expanded-form))
            expanded-form)))
#'user/my-eval

首先进行基本案例测试:

user> (my-eval '(or x (or y false)))
(or x y)

然后稍微递归:

user> (my-eval '(or (or x false) (or y false)))
(or x y)