2017-12-18 141 views
1

我的問題是關於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

回答

1

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

0

似乎to-symbol-list變成"(not b)"串的象徵,而不是一個嵌套列表。爲了解決這個問題,你需要重構這個函數來考慮parens。假設它看起來像(作爲字符串的第一個符號,它會自動調用它自己遞歸地將結果附加到某種累加器中(SICP充滿了這種練習)。