这是clojure.core.match bug还是&x27;只有我吗?
在第一个代码片段中,我希望它返回这是clojure.core.match bug还是&x27;只有我吗?,clojure,pattern-matching,clojure-core.match,Clojure,Pattern Matching,Clojure Core.match,在第一个代码片段中,我希望它返回:a1 奇怪 这项工作: (match [[1 2 3]] [(:or [_ _ 2] [3 _ _])] :a0 [(:or [_ _ 1] [1 _ _])] :a1 :else :else) => :else 这是一种预期行为吗?我想说,这不是因为手册中从未提到您使用:或的方式。应该用在这样的表达中: (match [[1 2 3]] [(:or [_ _ 2]
:a1
奇怪
这项工作:
(match
[[1 2 3]]
[(:or [_ _ 2]
[3 _ _])] :a0
[(:or [_ _ 1]
[1 _ _])] :a1
:else :else)
=> :else
这是一种预期行为吗?我想说,这不是因为手册中从未提到您使用
:或的方式。应该用在这样的表达中:
(match
[[1 2 3]]
[(:or [_ _ 2]
[1 _ _])] :a0
[(:or [_ _ 1]
[3 _ _])] :a1
:else :else)
=> :a0
因此,您的代码应该更像
[4 (:or 5 6 7) _] :a1
但也许你应该和作者商量一下。很难说原意是什么。我相信这是specialize或pattern row
中的一个bug。我相信那里的groupable?
测试是错误的,因为在您的例子中,它对两个或模式
s成功,因此第二个或模式
被第一个的扩展所取代(ps
是第一个或模式
的子模式)
您可以通过在第二个:或中添加虚拟模式来解决此问题,这将强制groupable?
返回false:
(match
[[1 2 3]]
[[_ _ 2]] :a0
[[3 _ _]] :a0
[[_ _ 1]] :a1
[[1 _ _]] :a1
:else :else)
可能更好的专门化或模式行
(复制为
,通过将:as
复制到每个子模式,在整个或模式上保留任何:as
元数据):
引述:
似乎是core.match中的一个bug。我使用了一个稍微简单一点的语句,它也有同样的问题
这也返回:else。我通过macroexpand运行它并提取逻辑。它变成了这样的东西
在第五行你可以看到错误,它是3而不是1。出于某种原因,它采用第一行:或模式中的值,而不是第二行的值
这似乎解决了问题
谢谢大家
附言:不过我还没有测试过这个补丁。这是一个非常有趣的问题,我得出了与您相同的结论。文档没有明确说明关于:或的意图,但它似乎只适用于标量值。
(match
[[1 2 3]]
[(:or [_ _ 2]
[1 _ _])] :a0
[(:or [_ _ 1]
[3 _ _]
:dummy)] :a1
:else :else)
(defn copy-as [dest src]
(if-let [as (-> src meta :as)]
(vary-meta dest assoc :as as)
dest))
(defn specialize-or-pattern-row [row pat ps]
(let [p (first row)]
(if (identical? p pat)
(map (fn [p] (update-pattern row 0 (copy-as p pat))) ps)
[row])))
(match
[[1]]
[(:or [3] [])] :a0
[(:or [1] [])] :a1
:else :else)
(let
[x [1]]
(cond (and (vector? x) (== (count x) 1) (= (nth x 0) 3)) :a0
(and (vector? x) (== (count x) 0)) :a0
(and (vector? x) (== (count x) 1) (= (nth x 0) 3)) :a1
(and (vector? x) (== (count x) 0)) :a1))