Reputation: 6010
I want to define an infinite list where each element is a function of all the previous elements.
So, the n+1
th element of the list would be f [x1, x2, ..., xn]
.
This seems simple, but I cannot seem to get my head around how to do it. Can anyone help?
Upvotes: 6
Views: 1181
Reputation: 12735
gen f = xs where xs = map f $ inits xs
Or
gen f = fix $ map f . inits
Upvotes: 11
Reputation: 144206
You can use unfoldr
:
import Data.List
gen :: ([a] -> a) -> a -> [a]
gen f init = unfoldr (\l -> let n = f (reverse l) in (Just (n, n:l))) [init]
note this has to reverse the input list each time. You could use Data.Sequence
instead:
import Data.Sequence
genSeq :: (Seq a -> a) -> a -> Seq a
genSeq f init = unfoldr (\s -> let n = f s in (Just (n, s |> n))) (singleton init)
Upvotes: 2
Reputation: 18381
As an alternative to the other answer, hopefully a little more readable but less laconic:
-- "heads f" will generate all of the the prefixes of the inflist
heads f = map ( (flip take) (inflist f) ) [1..]
-- inflist will generate the infinite list
inflist f = ( f [] ) : map f (heads f)
-- test function
sum1 s = 1 + sum s
-- test run
>> take 5 (inflist sum1)
[1,2,4,8,16]
Upd:
As pointed above the heads
function can be replaced with inits
, which I wasn't aware of it's existence.
Upvotes: 4