Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I merge a finite number of infinite lists in Haskell?

For an assignment I need to write some Haskell code which has as input a finite list consisting of infinite lists of integers, each list monotonically increasing.

Now, I need to merge these into one single list which orders the integers. Also, some integers may appear in multiple lists: in the output list, each integer may only appear once in the list.

So if the input is for example [ [1, 2, 6, 10, 28, 40, ...] [3, 4, 10, 28, 100, ...] , [any number of lists] ] then the output should be [1, 2, 3, 4, 6, 10, 28, 40, 100, ...]

I am a little stuck here. I do not know how to use foldr effectively to merge the lists. I think I should compare the heads of each list and make a new list out of that one.

like image 257
surfer1311 Avatar asked Oct 01 '14 20:10

surfer1311


People also ask

Can Haskell have infinite list?

As you all know, lists in Haskell can be infinite. This capability is a natural consequence of Haskell's lazy evaluation. An infinite list in Haskell is no problem since Haskell will lazily generate only as much of the list as is needed, when it is needed.

How do you make an infinite list in Haskell?

But in Haskell, you only need to allocate space for the items in the list that actually get evaluated. The two most basic functions for creating an infinite list are "repeat" and "cycle". The first makes an infinite number of the same element, while the second allows you to cycle through a specific series of elements.


1 Answers

You can simplify the problem a bit by thinking about merging two infinite sorted lists, and then try to generalize. The skeleton of that merge will look something like this:

mergeSorted :: Ord a => [a] -> [a] -> [a]
mergeSorted [] ys = ys
mergeSorted xs [] = xs
mergeSorted (x:xs) (y:ys) = ???

You'll have to compare x and y, and do something sensible, probably involving a recursive call to mergeSorted: this doesn't look too bad, right?

Now, let's imagine that mergeSorted works, and you can turn two infinite sorted lists into one infinite sorted list. How do you turn N infinite sorted lists into a single sorted list? Why, that's a simple fold! Just merge two lists together, then merge a third with that one, and a fourth with that one, and so on.

mergeAll :: Ord a => [[a]] -> [a]
mergeAll xss = foldr ???
like image 91
amalloy Avatar answered Nov 16 '22 00:11

amalloy