Clojure简单模式匹配

| 作为我上一个问题的跟进,我试图在Clojure中实现一个简单的模式匹配。 我想要以下内容:
(match target
  [ub]    expr1    ; ub should be bound to actual value in expr1
  [\'< ub] expr2    ; match the literal less-than symbol
                   ; and ub should be bound to actual value in expr2
  [lb ub] expr3    ; lb and ub should be bound to actual values in expr3
  :else   expr4    ; default case if none match
)
用法:
(match [< 5.0] ...)
应该安排在运行时执行
expr2
。 我想写一个宏,但不确定扩展。 我正在考虑将每个大小写从句扩展到带有内部变量绑定的
let
,并检查文字符号(
\'<
)是否确实与该模式匹配。也许是第二种模式(
[\'< ub]
):
(let [[sym1 ub] pattern]
  (if (= \'< sym1)
    expr1)
我需要使用ѭ7来绑定吗?怎么样? 大图:
(range-case target
            [0.0 < 1.0] :greatly-disagree
            [< 2.0]     :disagree
            [< 3.0]     :neutral
            [< 4.0]     :agree
            [5.0]       :strongly-agree
            42          :the-answer
            :else       :do-not-care)
我正在尝试匹配
[...]
模式并将其转换为以下格式:
[ub]          (if previous-ub `(and (<= ~previous-ub ~target) (<= ~target ~ub))
                              `(< ~target ~ub))
[\'< ub]       (if previous-ub `(and (<= ~previous-ub ~target) (< ~target ~ub))
                              `(< ~target ~ub))
[lb ub]       `(and (<= ~lb ~target) (<= ~target ~ub))
[\'< lb ub]    `(and (< ~lb ~target) (<= ~target ~ub))
[lb \'< ub]    `(and (<= ~lb ~target) (< ~target ~ub))
[\'< lb \'< ub] `(and (< ~lb ~target) (< ~target ~ub))
我有一个
cond
,用于检查案例部分是否为向量。该模式匹配应在这种情况下发生。     
已邀请:
        我的第一个想法基本上是相同的:将内容绑定到内部本地人,并在12英镑的大笔钱中对其内容进行测试。对于文字,值绑定到生成的本地;符号直接在绑定中使用。 我还添加了一个检查,以确定规格向量与目标向量的长度匹配。否则,您将无法同时拥有
[ub]
[lb ub]
,因为两者都不包含可能会失败的支票。因此,始终会选择第一个。 这是代码:
(defn make-clause
  [expr-g [spec expr & more :as clause]]
  (when (seq clause)
    (let [tests-and-bindings (map (fn [x]
                                    (if-not (symbol? x)
                                      (let [x-g (gensym \"x\")]
                                        [`(= ~x ~x-g) x-g])
                                      [nil x]))
                                  spec)
          tests    (keep first tests-and-bindings)
          bindings (map second tests-and-bindings)]
      `(let [[~@bindings] ~expr-g]
         (if (and (= (count ~expr-g) ~(count spec)) ~@tests)
           ~expr
           ~(make-clause expr-g more))))))

(defmacro match
  [expr & clauses]
  (let [expr-g  (gensym \"expr\")]
    `(let ~[expr-g expr]
       ~(make-clause expr-g clauses))))
并举例扩展。我没有在示例中使用语法引号来减少扩展中的噪音,但是您应该明白这一点。
(let [expr98 [(quote <) 3.0]]
  (let [[ub] expr98]
    (if (and (= (count expr98) 1))
      (if previous-ub
        (and (<= previous-ub target) (<= target ub))
        (< target ub))
      (let [[x99 ub] expr98]
        (if (and (= (count expr98) 2) (= (quote <) x99))
          (if previous-ub
            (and (<= previous-ub target) (< target ub))
            (< target ub))
          (let [[lb ub] expr98]
            (if (and (= (count expr98) 2))
              (and (<= lb target) (<= target ub))
              nil)))))))
发票是:
(match [\'< 3.0]
  [ub]    (if previous-ub
            (and (<= previous-ub target) (<= target ub))
            (< target ub))
  [\'< ub] (if previous-ub
            (and (<= previous-ub target) (< target ub))
            (< target ub))
  [lb ub] (and (<= lb target) (<= target ub))))
希望对您有所帮助。     

要回复问题请先登录注册