At university my task is the following :
define the following function:
primepowers :: Integer -> [Integer]
that calculates the infinite list of the first n powers of the prime numbers for a given parameter n, sorted asc. That is, primepowers n contains in ascending order the elements of
{p^i | p is prime, 1≤i≤n}.
After working on this task I came to a dead end. I have the following four functions:
merge :: Ord t => [t] -> [t] -> [t]
merge [] b = b
merge a [] = a
merge (a:ax) (b:bx)
| a <= b = a : merge ax (b:bx)
| otherwise = b : merge (a:ax) bx
primes :: [Integer]
primes = sieve [2..]
where sieve [] = []
sieve (p:xs) = p : sieve (filter (not . multipleOf p) xs)
where multipleOf p x = x `mod` p == 0
powers :: Integer -> Integer -> [Integer]
powers n num = map (\a -> num ^ a) [1..n]
primepowers :: Integer -> [Integer]
primepowers n = foldr merge [] (map (powers n) primes)
I think that they work independently, as I have tested with some sample inputs. merge merges two ordered lists to one ordered list primes returns infinite list of prime numbers powers calculates n powers of num (that is num^1 , num^2 ... num^n)
I try to merge everything in primepowers, but functions are not evaluated nothing happens respectively theres some kind of infinite loop.
I am not interested in optimization of primes or powers. Just I don't understand why that does not work. Or is my approach not good, not functional, not haskell?
I suspect the problem is: primes
is an infinite list. Therefore, map (powers n) primes
is an infinite list of (finite) lists. When you try to foldr merge []
them all together, merge
must evaluate the head of each list...
Since there are an infinite number of lists, this is an infinite loop.
I would suggest transposing the structure, something like:
primepowers n = foldr merge [] [map (^i) primes | i <- [1..n]]