【问题标题】:Can you Simplify a "Not Expression" in Clojure? [closed]你能在 Clojure 中简化一个“非表达式”吗? [关闭]
【发布时间】:2020-03-13 23:15:31
【问题描述】:
(defn eval-not

  [input]

 (cond

(and (seq? (second input)) (= 'and (first (second input)))) ;(do x here which -> (or (not x) (not y))
))

用户将输入 (eval-not '(not (and x y))) 并且我希望它返回 => (or (not x) (not y))。在保持 cond 使用的同时这是否可能。宁愿不使用宏,谢谢。

【问题讨论】:

  • 如果您不使用宏,您认为input 会得到什么?
  • 宏可以做到这一点,但为什么呢?此外,只有宏可以重写代码,这就是您所要求的)。
  • 一个函数可以接受引用列表'(not (and x y)) 并返回引用列表'(or (not x) (not y)),我认为这是我们想要的。真正的问题是,除了“有可能吗?”之外没有其他问题,没有进行过尝试或研究。
  • 我的尝试是上面写的代码。我在问如何开始这样做

标签: clojure


【解决方案1】:

这是一个关于遵循布尔运算规则的列表操作的问题。无需学习宏。

你开始走在正确的轨道上,但需要弄清楚:

  • 要应用的规则(例如,not 超过 and 看起来像 (not (and x y))(or (not x) (not y))但也适用于 not 超过 notor 等等,
  • 何时应用递归(例如,not 如果参数是一个序列,则可以分发,但非序列结束递归)并再次调用eval-not,小心。

请记住,您的函数的返回值将是列表,因此您需要构建一个列表作为返回值。对于您的第一种情况,您的列表需要以符号or 开头,因此cond 中第一个测试表达式旁边的返回值将如下所示:

(list 'or (eval-not (list 'not x)) (eval-not (list 'not y)))

...其中xy 是输入的实际部分,位于input 的第二个元素中的and 之后。

我建议您检查输入本身是否是一个序列,这样您就可以开始为这些部分命名,否则代码很快就会变得混乱。

有了上面的代码,代码开始看起来像这样:

(defn eval-not [input]

  (cond

    ;; when these happen
    (and (= 'not (first input))
         (seq? (second input))
         (= 'and (first (second input))))
      ;; then
      (let [x (nth (second input) 1)
            y (nth (second input) 2)]
        ;; distribute `not` over `and` here...

    ;; other cases...
    ))

希望在不为你解决作业的情况下对你有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 2013-01-16
    • 2011-04-11
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多