0

我的问题是关于 Clojures deftest 宏或更一般地关于如何比较由函数创建的列表。但我是 Clojure 的新手,无法识别具体原因。也许其他人有想法?

首先报告的消息:

(to-symbol-list-test) (util_test.clj:105)
预期失败:(= (quote (a (not b) c)) (to-symbol-list ["a" "(not b)" " c"]))
实际:(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"]))))

三、to-symbol-list的定义:

(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))

该函数甚至应该转换嵌套向量。这是一个示例,其他函数的行为方式相同。我猜这可能是由不同类型引起的。例如列表与惰性序列,我比较惰性函数而不是数据,但类型似乎是正确的。在 REPL 我得到:

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

2 回答 2

1

to-symbol-list返回 3 个符号的列表,并且不递归处理嵌套数据结构。不幸的是,第二个符号的打印结果与您期望的正确解析的数据结构相同。我认为在这种情况下,您最好使用clojure.edn/read-string此处的文档),它将解析您的数据结构,正如我认为您所期望的那样。

(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))))))
于 2017-12-18T14:19:51.247 回答
0

似乎to-symbol-list"(not b)"字符串变成符号,而不是嵌套列表。要解决这个问题,您需要重构该函数以考虑括号。比如说,如果它看到(字符串的第一个符号,它会调用自己递归地将结果附加到某种累加器中(顺便说一下,SICP 充满了这样的练习)。

于 2017-12-18T13:40:47.873 回答