我目前正在实施Project Euler 问题 40,并试图弄清楚如何从 Haskell 中的列表中获取多个项目,而无需重新开始列表。
目前,我有一个champernowne
类型列表Integral a => [a]
,它将返回一个无限的尚佩诺恩常数数字列表,然后我从这个序列中取出第一个、第十个等项并将它们相乘以获得答案。实际的代码是:
ans = (product . map (champernowne !!)) [0, 9, 99, 999, 9999, 99999]
这个实现的问题是(我假设)Haskell 每次想要获得一个新术语时都会从序列的开头遍历列表。我怎样才能使haskell只遍历从元素1到1 000 000的序列,然后将这些术语从中间拉出来?我已经尝试过 scanl 希望惰性评估能帮助我,但它没有:
ans = (product . head . scanl (flip drop) champernowne) [10, 90, 900, 9000, 90000]
只是为了澄清一下,第一段代码确实有效,但我正在努力改进我的实现以提高效率。