Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这是clojure.core.match bug还是&x27;只有我吗?_Clojure_Pattern Matching_Clojure Core.match - Fatal编程技术网

这是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))