首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优化Haskell中的“列表”索引

优化Haskell中的“列表”索引
EN

Stack Overflow用户
提问于 2014-01-13 22:55:38
回答 1查看 207关注 0票数 4

假设您有一个非常确定的算法,它生成一个列表,如inits in Data.List。Haskell编译器是否可以在不实际生成所有中间结果的情况下对该算法执行“索引”操作?

例如,inits [1..] !! 10000非常慢。编译器能以某种方式推断出inits会在第10000个元素上产生什么,而不需要任何递归等等?当然,这一想法也可以推广到清单之外。

编辑:虽然inits [1..] !! 10000是常量,但我想知道在某些算法上是否存在“类似索引”的操作。例如,可以对\i -> inits [1..] !! i进行优化,使其不执行或最小的递归来达到任何i的结果。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-14 01:23:46

是也不是。如果您查看Data.List.inits的定义

代码语言:javascript
复制
inits                   :: [a] -> [[a]]
inits xs                =  [] : case xs of
                                  []      -> []
                                  x : xs' -> map (x :) (inits xs')

您将看到它是递归定义的。这意味着生成列表的每个元素都构建在列表的前一个元素上。因此,如果您想要任何第n个元素,您必须构建所有的n-1以前的元素。

现在您可以定义一个新函数了。

代码语言:javascript
复制
inits' xs = [] : [take n xs | (n, _) <- zip [1..] xs]

有着同样的行为。如果您尝试接受inits' [1..] !! 10000,它完成得非常快,因为列表中的连续元素不依赖于前面的元素。当然,如果您实际上是试图生成一个init列表,而不是仅仅一个元素,这会慢得多。

编译器必须知道很多信息,才能优化像inits这样的函数的递归。也就是说,如果一个函数真的是“非常确定的”,那么用一种非递归的方式重写它应该是微不足道的。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21103043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档