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

使用返回子列表的函数在haskell中创建无限递归列表,haskell,recursion,Haskell,Recursion,我正试图解决一个问题。我想创建整数螺旋中的元素列表 我有以下功能: 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

我正试图解决一个问题。我想创建整数螺旋中的元素列表

我有以下功能:

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\u four\u number函数创建这个infinte序列?当然,我希望它能够有效地映射这一点,我希望能够这样做,例如:

take 20000 ( filter is_prime diagonal_spiral_numbers )
谢谢


ps:当然我正在学习haskell,这可能比我想象的要容易。

你可以这样做:

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函数:结果列表可以用许多更简单的方法生成,我认为总体上更好。

如果有一个函数可以基于上一个生成下一个状态,那么可以使用iterate函数来创建整个列表。在本例中,状态由四个数字和大小组成。在调用iterate之后,我调用map fst来去除大小值,并调用concat来连接所有列表

nextState (prev,size) = (next_four_numbers (last prev) size, size+2)
allNums = concat $ map fst $ iterate nextState ([1],3)

当然可以这样做,生成一个列表列表,然后检查concatMap函数,但通常的方法是让helper函数获取一个额外的tail参数,然后返回a:b:c:d:tail

另一种方法是使用zipWith3。

请注意,对于0,1,2,3

您只需要使用这些参数中的每一个调用下一个四个号码。这可以通过列表理解来实现:

diagonals = [next_four_numbers ((2*x+1)*(2*x+1)) (2*x+3) | x <- [0..]]
然后,只需将列表展平并准备1:

actual_diagonals = 1:concat diagonals
main = print (take 20 actual_diagonals)
这可能会被清理一点,但我会留给你;
顺便说一句,[0..]只是无限列表0,1,2,3,…

的简写,我认为问题并不那么清楚。你需要什么样的清单,它应该如何包含?您可以发布一个项目链接吗?这是project Euler,有一个输入错误,n应该是\p->n+p*size-1中的最后一个。这只是一段代码,对于如何理解或派生此类代码,没有任何解释、见解或指导-1[a,b,c,d]=。。。是一种更具可读性的匹配四元素列表的方法。
actual_diagonals = 1:concat diagonals
main = print (take 20 actual_diagonals)