haskell - Is getLine lazy? -
is getline
lazy?
say have long line on input. it's sequence of numbers. need sum 3 first numbers. getline
efficient , read first part of line, or have create own function lazy line reading, read characters 1 one?
will implementation efficient if sum whole line? (will there overhead due reading characters 1 one?)
import control.applicative main = line <- getline' print $ sum $ map read $ take 3 $ words line getline' :: io string getline' = c <- getchar if c == '\n' return [] else (c:) <$> getline'
while getline
isn't lazy, getcontents
is, , can combined functions lines
, words
. therefore, following program read enough of stdin (up to) 3 integers first line , print sum:
main :: io () main = contents <- getcontents let lns = lines contents result = sum $ map read $ take 3 $ words $ head lns print (result :: integer)
note that, if modify program access subsequent lines -- example, if added:
putstrln $ take 80 $ lns !! 1
to bottom of program print first 80 characters of second line, program have finish reading first line (and hang bit between last 2 lines of program) before processing first 80 characters of second. in other words, lazy line reading useful if only need read first bit of first line, if wasn't obvious -- haskell doesn't have magic way skip rest of first line second.
finally, note that, above program, if there fewer 3 integers on first line, it'll sum numbers , won't try read past first line (which think wanted). if don't care line endings , want sum first 3 numbers in file, regardless of how they're divided lines, can break contents directly words so:
main = contents <- getcontents let result = sum $ map read $ take 3 $ words contents print (result :: integer)
Comments
Post a Comment