簡體   English   中英

Haskell中列表理解的評估

[英]Evaluation of list-comprehensions in Haskell

我確切地想知道在Haskell中如何評估列表綜合。 閱讀完《 刪除語法糖》之后:在Haskell中理解列表,以及以下內容: Haskell懶惰的評估和重用我還是不太了解

[<function> x|x <- <someList>, <somePredicate>]

實際上完全等效(不僅在結果上,而且在評估上)

filter (<somePredicate>) . map (<function>) $ <someList>

如果是的話,這是否意味着可以僅使用所需元素來顯着降低所需列表的時間復雜度? 此外,這在無限列表方面如何工作? 具體來說:我假設類似:

[x|x <- [1..], x < 20]

將在有限時間內進行評估,但是在編譯器考慮的前提下,沒有更多的元素滿足謂詞的值,這個事實有多“明顯”呢?

[x|x <- [1..], (sum.map factorial $ digits x) == x]

工作(請參閱項目Euler問題34 https://projecteuler.net/problem=34 )。 顯然有一個上限,因為從x * 9上的x開始! <10 ^ n -1始終成立,但是我需要提供該界限嗎?還是編譯器會找到它?

一個特定的無限序列不再有與謂詞匹配的元素這一事實並沒有顯而易見的事實。 當您將列表傳遞給filter ,除了可以將元素傳遞給謂詞之外,它無法知道元素的任何其他屬性。

您可以編寫自己的Ord a => List a版本, Ord a => List a版本可以描述一個序列是否升序,以及可以使用此信息停止查看超過特定閾值的元素的filter版本。 不幸的是,列表理解將不會使用它們中的任何一個。

相反,我會結合使用takeWhile和不帶謂詞/純map的理解。 takeWhile參數中的takeWhile ,您將向編譯器提供有關預期上限的信息; 對於n個十進制數字,它將是10 ^ n

[<function> x|x <- <someList>, <somePredicate>]

應始終計算相同的結果,

filter (<somePredicate>) . map (<function>) $ <someList>

但是, 不能保證編譯器將實際執行此操作。 在Haskell的報告列表理解的部分只提到什么列表內涵應該做的,他們不應該是如何工作的。 因此,每個編譯器都可以自由地按照開發人員的最佳狀態來做。 因此,您不應假設任何有關列表推導的性能,否則編譯器將進行任何優化。

暫無
暫無

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

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