簡體   English   中英

Clojure lazy-seq自然數

[英]Clojure lazy-seq Natural Numbers

一個流行的在線教程提供了以下示例以構建自然數:

(def infseq (map inc (iterate inc 0)))

例如, (take 5 infseq)給出:

1 2 3 4 5

我可以看到(iterate inc 0)功能,但是,總的來說,我不知道發生了什么。 (例如,這不是正常的函數定義。)

有人可以解釋一下嗎?

讓我們分解一下這個表達式:

(map inc (iterate inc 0)))

是具有以下結構的列表(數據結構):

(function-to-call function-passed-as-first-srgument another-list-as-second-arg)

現在,讓我們從內到外對其進行探索!
該內部列表:

(iterate inc 0)

有這個結構

(function-to-call function-passed-as-first-argument number)
  • 被調用的函數是iterate ,它通過跟蹤內部狀態來創建無限序列,每當需要一個新值來使序列變長時,它就將傳遞的函數作為第一個參數並在當前函數上調用州。
  • 作為第一個參數傳遞的函數是inc ,該數字為numbr,並添加一個
  • iterate的第三個參數是初始狀態。 它應該從哪里開始。

因此,當評估此內部表達式時,它將立即返回表示列表的數據結構,而尚未實際構建該列表。 從該列表中讀取第一個值時,它將返回初始值0 ,當要求第二個值時,它將使用inc函數得出數字1 如果再次需要第一個或第二個值,它們將照原樣使用,而不重新計算。

因此,第一個參數表示產生所需數量的合同。 這本身就是原始表達式的第三個參數。

初始表達式采用該惰性列表並創建一個新的惰性列表。

這個新的惰性列表由map函數返回。

(map inc (0 1 2 3 4 ... as many as you read ...))

它將在讀取時將inc應用於其中的每一個,並且僅在讀取時才使用(實際上,它會提前緩存20個左右的項目,以使其速度更快一點),從而導致以下順序:

((inc 0) (inc 1) (inc 2) (inc 3) ... as much as you read from the sequence ...)

得出以下結果:

(1 2 3 4 ... created lazily)

這些等效表達式的結果相同,

(rest (range))

(iterate inc 1)

和許多其他形式。

出於示例的目的 ,我們可以定義mapiterate如下iterate

(defn iterate [f init]
  (lazy-cons init (iterate f (f init))))

(defn map [f [x & xs]]
  (lazy-cons (f x) (map f xs)))

...其中lazy-cons是一個版本cons ,不采取行動,直到它必須如此。 它曾經是clojure.core一部分,因此可能已定義為:

(defmacro lazy-cons [x xs]
  `(lazy-seq (cons ~x ~xs)))

要理解這些定義,您需要掌握遞歸,惰性,解構和宏:這是一項艱巨的任務! 但是這樣做,您將真正了解clojure的序列庫(包括iteratemap )如何工作。 這就是我學到的東西。


iterate的定義有效。 map僅適用於單個無窮序列參數。

(take 5 (iterate inc 0)) => (0 1 2 3 4)

反復iterate應用inc函數。 您從0開始,所以您得到[0 1 2 3 ...]

(take 5 (map inc (iterate inc 0))) => (1 2 3 4 5)

(map inc <collection>)一次將inc應用於(map inc <collection>)中的每個項目,將先前的結果轉換為[1 2 3 4 ...]

(take 5 (range)) => (0 1 2 3 4)

range帶任何參數的range從0開始並永遠計數,與第一個示例相同。

由於所有這些集合的長度都是無限的,因此我們需要類似的東西(take 5 <collection>)來限制打印內容的長度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM