如果比较列表,Clojure的默认宏中的声明错误

问题描述:

我的问题是关于Clojures deftest宏或更一般的关于如何比较由函数创建的列表的问题。但我对Clojure很陌生,无法识别具体的原因。也许别人有想法?如果比较列表,Clojure的默认宏中的声明错误

首先报道的消息:

FAIL在(到符号列表检验)(util_test.clj:105)
预期:(=(引号(一个(非B)c))的(to-symbol-list [“a”“(not b)”“c”]))
actual:(not(=(a(not b)c)(a(not b)c)))

但是很明显,(=(a(not b)c)(a(not b)c))引用应该是真实的。

其次具体的测试代码:对符号表的

(deftest to-symbol-list-test 
(is (= '(a (not b) c) (to-symbol-list ["a" "(not b)" "c"])))) 

三定义:

(defn to-symbol-list [term] 
    "Converts a vector based term into a list based term 
    by converting its elements into symbols recursivly" 
    (postwalk 
    #(if (string? %) 
     (symbol %) 
     (reverse (into '() %))) 
    term)) 

功能甚至应该转换嵌套向量。这是一个例子,其他功能以相同的方式表现。我猜想它可能是由不同类型造成的。例如列表vs lazy-seq和我比较惰性函数而不是数据,但类型似乎是正确的。在REPL我得到:

(type (to-symbol-list ["a" "(not b)" "c"])) 
=> clojure.lang.PersistentList 
+0

我认为你正在下降陷阱'(符号“(没有B)”)' – cfrick

+0

你是对的,多数民众赞成的问题,谢谢:) – Daniel

to-symbol-list返回3个符号的列表,并且不递归处理嵌套的数据结构。不幸的是,第二个符号的打印方式与您所期望的正确解析的数据结构相同。我认为在这种情况下,使用clojure.edn/read-stringdocs here)会更好,这将解析您的数据结构,因为我认为您期待。

(defn to-symbol-list [list-of-strings] 
    (map edn/read-string list-of-strings)) 

(to-symbol-list ["a" "(not b)" "c"]) 

而且,作为一个提示,以帮助诊断这类在未来的事情,你可以传递一个额外的参数来clojure.test/is将在出现故障的情况下打印出来。这可能是一个函数调用的结果,如:

(ns to-symbols-test 
    (:require [clojure.edn :as edn] 
      [clojure.test :refer [deftest is are testing] :as t] 
      [clojure.data :as data] 
      [clojure.pprint :as pp])) 

(defn to-symbol-list [l] 
    (map edn/read-string l)) 

(defn diff [a b] 
    (with-out-str (pp/pprint (take 2 (data/diff a b))))) 

(deftest test-to-symbol-list 
    (testing "to-symbol-list should convert recursively" 
    (let [expected '(a (not b) c) 
      result (to-symbol-list ["a" "(not b)" "c"])] 
     (is (= expected result (diff expected result)))))) 
+0

谢谢很多为您的详细答案和差异的线索。将您的功能与我的合并,将评估解决为真实。合并,因为递归我并不意味着在字符串中下降,而是甚至解析这样的东西:[“或” [“和”“(不是a)”“b”“c”] [“和” “a”“(not b)”“c”] [“and”“a”“b”“(not c)”] [“and”“a”“b”“c”]] – Daniel

似乎to-symbol-list变成"(not b)"串的象征,而不是一个嵌套列表。为了解决这个问题,你需要重构这个函数来考虑parens。假设它看起来像(作为字符串的第一个符号,它会自动调用它自己递归地将结果附加到某种累加器中(SICP充满了这种练习)。