[英]create an infinite recursive list in haskell using a function returning a sublist
我正在尝试解决项目欧拉问题。 我想以整数螺旋形式创建元素列表。
我有功能:
next_four_numbers last size = map (\p -> last + p*(size-1)) [1,2,3,4]
我当然有生成它的其他方法,但是最后我想拥有无限的顺序:
对角线螺旋数= [1,3,5,7,9,13,17,21,25,31,37,43,49 ...]
我怎样才能使用我的“ next_four_numbers”函数创建这个无限序列? 当然,我希望它能够有效地对此进行映射(例如,我希望能够这样做):
take 20000 ( filter is_prime diagonal_spiral_numbers )
谢谢,
ps:当然,我正在学习haskell,这可能比我想象的要容易。
如果您有一个根据前一个状态生成下一个状态的函数,则可以使用iterate
函数来创建整个列表。 在这种情况下,状态由四个数字和大小组成。 调用迭代后,我打电话map fst
摆脱的size
值和concat
来连接所有列表。
nextState (prev,size) = (next_four_numbers (last prev) size, size+2)
allNums = concat $ map fst $ iterate nextState ([1],3)
您可以这样做:
diagonal_spiral_numbers =
let helper l s =
let next_four_numbers last size = map (\p -> last + p*(size-1)) [1,2,3,4]
(a:b:c:d:[]) = next_four_numbers l s
in a:b:c:d : helper d (s+2)
in 1 : helper 1 3
这里的输出:
take 20 diagonal_spiral_numbers
[1,3,5,7,9,13,17,21,25,31,37,43,49,57,65,73,81,91,101,111]
但是我想知道为什么您需要使用next_four_numbers
函数:可以用许多更简单(并且我会说总体上更好 )的方式生成结果列表。
当然可以通过这种方式完成:生成列表列表,然后将其展平 (检查concatMap函数),但是通常的方法是让您的辅助函数使用附加的“ tail”参数,然后返回a:b: C:d:尾巴。
另一种方法是使用zipWith3。
请注意,您的last
和size
参数始终分别为(2x+1)^2
和2x+3
(对于x
in 0,1,2,3,...
)
您只需要使用这些参数中的每一个调用一次next_four_numbers。 这可以通过列表理解来实现:
diagonals = [next_four_numbers ((2*x+1)*(2*x+1)) (2*x+3) | x <- [0..]]
或使用地图(如果您对此更满意):
diagonals = map (\x -> next_four_numbers ((2*x+1)*(2*x+1)) (2*x+3)) [0..]
然后,只需弄平列表并添加1:
actual_diagonals = 1:concat diagonals
main = print (take 20 actual_diagonals)
这可能可以清除一点,但我将留给您;)顺便说一句, [0..]
只是无限列表0,1,2,3,...
简写0,1,2,3,...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.