Tuesday, April 28, 2009

Merging an infinite list of infinite lists

A paper I was reading today for class contained a problem that I thought was interesting: How do you merge an infinite list of infinite lists such that every element in the list is indexable? The paper introduced a monadic solution using faux-concurrency that was pretty cute, but it got me thinking about a simpler solution.

In an effort to maintain my nerd credentials after my spate of sports posts, I figured I'd throw my code up here and call it content. This is the sort of stuff I procrastinate with all the time, so if anyone's interested in mostly useless snippets of Haskell code, maybe I'll do this more regularly.

merge :: [[a]] -> [a]
merge ls = [ls !! x !! y | (x,y) <- p 0 0]
where p 0 y = (0,y) : p (y+1) 0
p x y = (x,y) : p (x-1) (y+1)

Pretty simple. p generates all pairs (x,y) in the order of the Cantor pairing function. x and y indicate which list, and which value in that list to return next.

An example application of this function in GHCi:

> take 10 $ merge [[i..] | i <- [100,200..]]
[100,200,101,300,201,102,400,301,202,103]

0 comments:

Post a Comment