Haskell
Haskell

Reputation: 125

Haskell, how to calculate divider from an infinite list?

How can I write a function which receives a list, for example [7, 8, 9].

The function has inside an infinite list. It will calculate all divisors from an infinite list.

For example take 5 (f [7, 8, 9]) output will be [7, 8, 9, 14, 16]

Second example take 7 (f [7, 8, 9]) output will be [7, 8, 9, 14, 16, 18, 21]

I hope you can understand what I mean.

My code looks like this:

myFunction list = [x | x <- [1..], el <-[list], x `mod` el == 0]

My code works only with constant list. If I write

myFunction list = [x | x <- [1..], el <-[7, 8], x `mod` el == 0]

It works only for 7 and 8

How can I pass an arbitrary list?

Upvotes: 0

Views: 250

Answers (1)

Dan Robertson
Dan Robertson

Reputation: 4360

First let’s solve the case for a single item instead of a list:

multiples n | n > 0 = [n * i | i <- [1..]]

That was easy enough. Now suppose we have multiples 2 and multiples 3, how can we compute multiples [2,3], i.e. the increasing sequence of numbers made of the multiples of 2 or 3, or in other words, the increasing list of numbers made that are either in the increasing list of numbers multiples 2 or multiples 3? Try this:

merge (x:xs) (y:ys) = case compare x y of
  GT -> y : merge (x:xs) ys
  LT -> x : merge xs (y:ys)
  EQ -> x : merge xs ys

So now we can implement the desired function:

f (x:xs) = foldr merge (multiples x) (multiples <$> xs)

Upvotes: 3

Related Questions