Why doesn't the following program print my input? It seems that putStr
is not taking the input. How does getContents
work?
main = do
contents <- getContents
when (length contents < 10) $ putStr contents
However, this program prints the input line by line:
main = do
contents <- getContents
putStr contents
getContents
gets the entire input from a handle (eg file or user input), so your program
main = do
contents <- getContents
putStr contents
reads the entire contents of the standard input and prints it. The only reason you see this line by line is that it's using linebuffering on the terminal, so getContents
gets its incoming String a line at the time.
Haskell uses lazy evaluation, which means it only calculates something when it has to - it doesn't need calculate the end of the string you're printing to print the start of it, so it doesn't bother, and just prints what it has now. This lazy functions are able to return partial results when they can, rather than having to calculate everything first.
You appear in comments to want to only print lines when they're short like this session:
don't print this it's long
print this
print this
this is also too long
boo!
boo!
but since getContents
is all the input, it won't print anything unless the total length is less than 10. What you were after was something where it treats each line separately, more like
main = do
contents <- getContents
putStrLn . unlines . filter short . lines $ contents
short xs = length xs <= 10