Haskell中无限懒惰的因子

时间:2014-10-22 12:23:46

标签: haskell lazy-evaluation factorial

与Fibonacci系列类似的方式可以生成如下,

fibs :: [Integer]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)

如何定义阶乘的系列。

更新

令人尴尬的是,在添加这个问题之前尝试了这个,

Prelude> let factorial = 2 : 6 : zipWith(*) factorial (tail factorial)
Prelude> take 5 factorial
[2,6,12,72,864]

确实,尾部的数字不是连续的值,首先是。

3 个答案:

答案 0 :(得分:7)

让我们退后一步,记住懒惰版本的实际来源:

fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

我们也可以类似地定义阶乘:

factorial 0 = 1
factorial n = factorial (n - 1) * n

正如您所看到的,我们的压缩操作实际上是(*),第二个列表不是factorials的子列表,而是[x..]具有适当的x 1}}:

factorials = 1 : zipWith (*) factorials [x..]

x应该有什么价值?好吧,第二个元素应该是1 = 1 * 1,所以它1,自然是:

factorials = 1 : zipWith (*) factorials [1..]

请注意,我们只需要提供第一个元素,因为我们不使用tail或类似的东西。如您所见,您的尝试几乎是正确的。您刚刚在左侧使用了错误的值:

Prelude> let factorial = 2 : 6 : zipWith (*) [4..] (tail factorial)
Prelude> take 10 $ factorial
[2,6,24,120,720,5040,40320,362880,3628800,39916800]

备注:阶乘序列为0!,1!,2!,...,因此,如果您希望符合OEIS,请以[1,1,...]开头。

答案 1 :(得分:5)

延迟的阶乘列表的惯用定义根本不是递归的:而是使用Prelude函数scanl

factorials = scanl (*) 1 [1..]

答案 2 :(得分:2)

考虑到factorial的通常定义:

factorial :: Integer -> Integer 
factorial 0 = 1
factorial i = foldr (*) 1 [2..i]

我们可以通过在所有正数的无限列表上运行factorial函数来生成所有阶乘的无限列表:

inFact :: [Integer]
inFact = map factorial [0..]

Live demo