Reputation: 20435
In a similar fashion as the Fibonacci series may be generated as follows,
fibs :: [Integer]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
how to define the series for factorial.
Update
Embarrassingly enough, tried this quite before adding this question,
Prelude> let factorial = 2 : 6 : zipWith(*) factorial (tail factorial)
Prelude> take 5 factorial
[2,6,12,72,864]
Indeed the numbers in the tail are not successive values, to start with.
Upvotes: 3
Views: 4636
Reputation: 381
factorials = helper [1..]
helper (x:xs) = x : help ([x * (head xs)] ++ (tail xs))
Upvotes: 0
Reputation: 105985
Lets take a step back and remember where that lazy version actually comes from:
fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
We can also define the factorial similarly:
factorial 0 = 1
factorial n = factorial (n - 1) * n
As you can see, our zipping operation is actually (*)
, and the second list won't be a sublist of factorials
, but instead [x..]
with an appropriate x
:
factorials = 1 : zipWith (*) factorials [x..]
What value should x
be? Well, the second element should be 1 = 1 * 1
, so it's 1
, naturally:
factorials = 1 : zipWith (*) factorials [1..]
Note that we only need to give the first element, since we don't use tail
or something similar. As you can see, your attempt was almost correct. You just used the wrong values for the left hand side:
Prelude> let factorial = 2 : 6 : zipWith (*) [4..] (tail factorial)
Prelude> take 10 $ factorial
[2,6,24,120,720,5040,40320,362880,3628800,39916800]
Remark: The factorial sequence is 0!, 1!, 2!, ..., so if you want to be OEIS compliant start with [1,1,...]
.
Upvotes: 9
Reputation: 15029
The idiomatic definition of a lazy list of factorials is not recursive at all: instead it uses the Prelude function scanl.
factorials = scanl (*) 1 [1..]
Upvotes: 7
Reputation: 76298
Given the usual definition of factorial
:
factorial :: Integer -> Integer
factorial 0 = 1
factorial i = foldr (*) 1 [2..i]
we can generate an infinite list of all factorials by simply running the factorial
function over an infinite list of all positive numbers:
inFact :: [Integer]
inFact = map factorial [0..]
Upvotes: 3