我無法圍繞序列和LazyList
之間的差異。他們既懶惰又潛力無限。而來自.NET框架的seq<'T>
是IEnumerable<'T>
,包含在F# PowerPack中。在實踐中,我比LazyList
更頻繁地遇到序列。序列與LazyList
它們在性能,用法,可讀性等方面有什麼不同?與seq
相比,LazyList
的聲譽如此差的原因是什麼?
我無法圍繞序列和LazyList
之間的差異。他們既懶惰又潛力無限。而來自.NET框架的seq<'T>
是IEnumerable<'T>
,包含在F# PowerPack中。在實踐中,我比LazyList
更頻繁地遇到序列。序列與LazyList
它們在性能,用法,可讀性等方面有什麼不同?與seq
相比,LazyList
的聲譽如此差的原因是什麼?
LazyList
無論列表遍歷多少次,每個元素只計算一次。通過這種方式,它更接近從Seq.cache
返回的序列(而不是典型的序列)。但是,除了緩存之外,LazyList
的行爲與列表完全相同:它在引擎蓋下使用列表結構並支持模式匹配。所以你可能會說:當你需要列表語義和緩存(除了懶惰之外)時,可以使用LazyList
而不是seq
。
關於兩者都是無限的,seq
的內存使用率是恆定的,而LazyList
的是線性的。
這些docs可能值得一讀。
除了丹尼爾的回答,我認爲主要的實際區別是你如何處理LazyList
或seq
結構(或計算)。
如果你要處理LazyList
,您通常會使用模式匹配(非常類似於普通F#列表的處理)
如果你要處理seq
,您可以用寫一個遞歸函數內置函數,或者你必須編寫調用GetEnumerator
的命令式代碼,然後在循環中使用返回的枚舉器(可以將其寫成遞歸函數,但它會改變枚舉器)。您不能使用通常的頭/尾樣式(使用Seq.tail
和Seq.head
),因爲這樣效率極低 - 因爲seq
不保留評估的元素,並且Seq.head
的結果需要從頭開始重新迭代。
關於seq
和LazyList
聲譽,我認爲F#庫設計採取務實的態度 - 因爲seq
實際上是.NET IEnumerable
,它是.NET編程比較方便(它也是因爲你好看可以將其他收藏品視爲seq
)。懶惰列表並不常見,因此在大多數情況下,正常的F#列表和seq
就足夠了。
+1,很酷,我不知道緩存部分。你能舉一個需要懶惰和列表語義的例子嗎? – pad 2012-02-08 21:19:25
遍歷一個序列,同時訪問多個元素可以使用'seq'來完成,但是使用'LazyList' +模式匹配更加簡潔。 – Daniel 2012-02-08 21:21:36
參見例如http://stackoverflow.com/questions/3484315/how-to-merge-sorted-sequences-in-f和http://stackoverflow.com/questions/1306140/f-why-is-using-a-sequence-如此慢得多使用列表中的這個例子/ 1306267#1306267 – Brian 2012-02-08 21:27:33