繁体   English   中英

使用返回子列表的函数在haskell中创建无限递归列表

[英]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会返回[3,5,7,9]
  • 使用参数9和5会返回[13,17,21,25]
  • 参数25和7会返回[31,37,43,49] ...

我当然有生成它的其他方法,但是最后我想拥有无限的顺序:

对角线螺旋数= [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。

请注意,您的lastsize参数始终分别为(2x+1)^22x+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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM