How to control laziness on the example of Double each element of the list

I tried to decide Duplicate each item in a Haskell List and make it like a complete program that writes a list to standard output

Here is my solution

main :: IO ()
main = getList >> = return. doubleEachItem >> = putStrLn. show

getList = return [1,3,5]

doubleEachItem :: [Int] -> [Int]
doubleEachItem = foldr (++) []. map (take 2. repeat)

But when I try to process a really long list

getList = return. take 1,000,000,000 $ repeat 15

The program ended with a memory error.

Question: how can I improve the program so that it can process lists of any size?

Edit:

, , runghc. ghc 3 . 0.6GBytes. .

native executable ghc haskell03.hs -o haskell03 ./haskell03 >out03.txt, 20 /. , 57GBytes. - 47 .

+3
4

! , , . .

runghc , ghci. getList - , ( , ) . , GHC .

, , :

main = putStrLn . show . doubleEachElement $ [1..10^10]

, main , [1..10^10], .

: - , . , . GHC , :

main = do
    n <- return (10^10)
    putStrLn . show . doubleEachElement $ [1..n]

getList, getList 10^10.

, GHC , , , , , .

, , . , , GHC , .

+7

, . , , , . , :

import System.IO
main = do
    hSetBuffering stdout NoBuffering
    getList >>= ...

, ,

main = getList >>= return . doubleEachItem >>= mapM_ print
+1

luqui

main :: IO ()
main = return 1 >>= getList >>= return . doubleEachElement >>= putStrLn . show

getList doNotCache = return . take (10^10) $ repeat 15

doubleEachElement :: [Int] -> [Int]
doubleEachElement = foldr (++) [] . map (take 2 . repeat)

.

luqui, getList , . haskell , , .

+1

To implement doubleEachItem with, you foldrneed the entire list built in memory, because it foldrstarts from the end of the list. To avoid this, replace foldrwith foldl'or rewrite the function as:

doubleEachItem = concatMap (replicate 2)
-1
source

Source: https://habr.com/ru/post/1780600/


All Articles