[Haskell-cafe] file line operation perhaps need loop

Arthur van Leeuwen arthurvl at cs.uu.nl
Wed Jul 20 03:24:39 EDT 2005


On Wed, Jul 20, 2005 at 02:27:36PM +0800, Sun Yi Ming wrote:
> Hello,
>   I have two txt file,and i want to mix the two files line by line, e.g. 
>  $ cat url1.txt
>    url1_1.line
>    url1_2.line
>  $ cat url2.txt
>    url2_1.line
>    url2_2.line
> and i want this file as result:
>  $ cat aha.txt
>    url1_1.line
>    url2_1.line
>    url1_2.line
>    url2_2.line
> 
> i first write this snippet of code:
> ---
> import System.IO
>     
> mix :: [a] -> [a] -> [a]
> mix [] ys = ys
> mix xs [] = xs
> mix (x:xs) (y:ys) = [x,y] ++ mix xs ys
> 
> f1 = do contents1 <- readFile "url1.txt"
>         contents2 <- readFile "url2.txt"
>         let urls1 = lines contents1
>             urls2 = lines contents2
>             urls = mix urls1 urls2
>         writeFile "aha.txt" (unlines urls)
> --
> this works fine, but i think if the two file are very big, and the 
> readFile will consume too many mem.

Ah, but this is exactly where lazyness wins bigtime: a smart implementation
of readFile will lazily read the actual file for as far as needed. Thus,
reading with readFile will not read the entire file into memory at once.
What will happen is that writeFile starts writing, and upon discovery of
needing the value of urls it will then start reading. Any value already
written in this case obviously turns into garbage and will be garbage
collected. I would be slightly surprised if this code uses more than
constant memory.

> so i need to read the file 
> line by line but stunned by the loop in IO Monad:
> ---
> main = do h1 <- openFile "url1.txt" ReadMode
>           h2 <- openFile "url2.txt" ReadMode
>           line1 <- hGetLine h1
>           line2 <- hGetLine h2
>           print $ line1 : line2 : [] -- i don't howto do
>           hClose h1
>           hClose h2
> --
> any ideas? thank you all.

Yes. You need to split the lines 

        line1 <- hGetLine h1
        line2 <- hGetLine h2
        print $ line1 : line2: []

into a separate function that will then recurse over the file.

Doei, Arthur.

-- 
  /\    / |       arthurvl at cs.uu.nl       | Work like you don't need the money
 /__\  /  | A friend is someone with whom | Love like you have never been hurt
/    \/__ | you can dare to be yourself   | Dance like there's nobody watching


More information about the Haskell-Cafe mailing list