-- 1ª definición (por comprensión):
productoInfinito1 :: [Integer] -> [Integer]
productoInfinito1 xs = [product (take n xs) | n <- [1..]]
-- 2ª definición (por recursión)
productoInfinito2 :: [Integer] -> [Integer]
productoInfinito2 (x:y:zs) = x : productoInfinito2 (x*y:zs)
-- 2ª definición (por recursión y map)
productoInfinito3 :: [Integer] -> [Integer]
productoInfinito3 [] = [1]
productoInfinito3 (x:xs) = map (x*) (1 : productoInfinito3 xs)
-- 4ª definición (con scanl1)
productoInfinito4 :: [Integer] -> [Integer]
productoInfinito4 = scanl1 (*)
-- Comparación de eficiencia
-- λ> take 20 (show (productoInfinito1 [2,4..] !! 10000))
-- "11358071114466915693"
-- (0.35 secs, 98,287,328 bytes)
-- λ> take 20 (show (productoInfinito2 [2,4..] !! 10000))
-- "11358071114466915693"
-- (0.35 secs, 98,840,440 bytes)
-- λ> take 20 (show (productoInfinito3 [2,4..] !! 10000))
-- "11358071114466915693"
-- (7.36 secs, 6,006,360,472 bytes)
-- λ> take 20 (show (productoInfinito4 [2,4..] !! 10000))
-- "11358071114466915693"
-- (0.34 secs, 96,367,000 bytes)