繁体   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