在Clojure中是一个无限空值序列的空列表?

时间:2009-07-23 20:27:17

标签: clojure

我正在学习Clojure中sequencenil的概念。这是一个小实验的结果。

1:6 user=> (first '())
nil
1:7 user=> (rest '())
()
1:8 user=> (first (rest '()))
nil

这是否意味着'()实际上是一系列的nils?

5 个答案:

答案 0 :(得分:10)

如果您想测试集合的“其余”是否为空,请使用next

user> (next '(foo bar))
(bar)
user> (next '())
nil
user> (doc next)
-------------------------
clojure.core/next
([coll])
  Returns a seq of the items after the first. Calls seq on its
  argument.  If there are no more items, returns nil.

“nil-punning”(处理空集合/ seq和nil同样的东西)去年被删除,有利于完全懒惰的序列。有关此更改的讨论,请参阅here

答案 1 :(得分:4)

firstrest是适用于逻辑结构(seq)的函数,而不是列表的链接cons结构(如在其他lisps中)。

  

Clojure根据序列(seqs)定义了许多算法。 seq是一个逻辑列表,与大多数Lisps不同,其中列表由具体的2槽结构表示,Clojure使用ISeq接口允许许多数据结构提供对其元素的序列访问。

     

http://clojure.org/sequences

行为是函数定义的结果,而不是由数据的原始结构决定的。

答案 2 :(得分:2)

- 空列表与无限的nils序列不同

这相对容易展示。假设我们有:

(def infinite-nils (repeat nil)) ; an infinite lazy sequence of nils
(def empty-list    '())          ; an empty list

他们有不同数量的元素:

(count infinite-nils) => doesn't terminate
(count empty-list)    => 0

取自他们:

(take 10 infinite-nils)  => (nil nil nil nil nil nil nil nil nil nil)
(take 10 empty-list)     => ()

如果你打电话给seq,你就得到了

(seq inifinite-nils) => sequence of infinite nils
(seq empty-list)     => nil

通过理解以下事实可以在很大程度上解决原文中的混淆:

  • '()是一个集合(持久列表),而不是序列。但它是顺序的,因此您可以在其上调用seq将其转换为序列。
  • nil是空序列 - 因此(seq '())返回nil,(seq (rest '()))
  • first在空序列中返回nil - 因此(first (rest '()))为零的原因。

答案 3 :(得分:1)

还学习Clojure。

对于空sequencesrest会返回seq返回nil的序列。

这就是你得到这种行为的原因。

我假设这是为了简化序列的递归,直到它们为空,并且可能是其他smartypants的原因......

答案 4 :(得分:0)

技术上虽然不是有用的。

“通过调用(seq'(())创建的序列是否具有无限数量的空值?”
答案是肯定的,因为空序列的(休息)是一个空序列它自己可以有一个(休息)

顺便说一下,这个输出会产生误导:

1:7 user=> (rest '())
()

这里的第一个'()是空列表 这里的secong()是空序列 序列的打印方式与repl中的列表相同,即使它们不相同。