为什么(=(运行1 [q](membero' cat q))['(cat。_.0)])是假的?

时间:2013-08-28 21:20:40

标签: clojure clojure-core.logic

我正在做clojure / core.logic koans并坚持this one

"Here we give run a specific number to control how many answers we get. Think
carefully. Is there only one list in the universe that satisfies this relation?
Are there infinitely many?"
 (= (run 1 [q]
       (membero 'cat q))
    [__])

在REPL中运行(run 1 [q] (membero 'cat q))说我答案是((cat . _.0))。我不太确定中间的点是什么意思,但无论如何,在原始公案中坚持'(cat . _.0)而不是__占位符并没有帮助(断言仍然失败)。你能指点我正确的方向吗?并解释cat_.0之间的点是什么意思?我的猜测是,它意味着后面的内容(即_.0)是任何长度的尾巴,但我不是100%肯定。 ===更新

amalloy向我指出了正确的方向(谢谢,先生!)。 lcons可以解决问题:

 (= (run 1 [q]
       (membero 'cat q))
    [(lcons 'cat '_.0)])

还有一点REPL:

user=> (lcons 'cat '_.0)
(cat . _.0)
user=> '(cat . _.0)
(cat . _.0)
user=> (= '(cat . _.0) (lcons 'cat '_.0))
false

点用于表示dotted lists。根据{{​​3}},虚线列表是一种不正确的列表,其中另一种是循环列表。因此,在上面的REPL会话中,第一个列表是带有两个元素('cat'_.0)的虚线列表,而第二个列表是包含三个元素('cat'的正确列表, '.'._0)。他们的字符串表示是相同的,但它们是不同的。

1 个答案:

答案 0 :(得分:2)

(a . b)表示法是来自其他lisps的遗留物,它使用cons单元构建不正确的列表。你是对的,它的意思是“符号cat后跟任何长度的任何列表”,但实际上它是core.logic LCons值的打印表示。没有简单的文字可以输入以生成该类型的值,因此您无法使用自己的值进行比较。但是,我希望LCons是可选的,因此您可以将(first the-thing)'cat进行比较,依此类推。