Haskell IO with interact and map
I am trying to produce an interactive Haskell program using the interact
function with map
.
Here's what I get in ghci (as far as I can tell, that's the way all tutorials explain interact
usage -- except the result).
*Module> interact $ unlines . map (++ "!") . lines
tteesstt
!
Note that what actually happens is that every character I type is instantly repeated and after I press Return the exclamation mark开发者_StackOverflow中文版 appears. I was, however, expecting this:
*Module> interact $ unlines . map (++ "!") . lines
test
test!
It works perfectly if I use the same program structure, but filter
instead of map
.
The problem is that ghci changes the buffering mode to per-character. This is, that the program starts to process the code as soon as it is there. If you write this line into a file called foo.hs
main = interact $ unlines . map (++ "!") . lines
and run it using runhaskell foo.hs
you will see that it works as expected, because Haskell uses line-buffering by default.
As FUZxxl says, it's a buffering issue.
To change buffering styles in GHCi, use hSetBuffering
Prelude> :m +System.IO
Prelude System.IO> hSetBuffering stdout LineBuffering
Prelude System.IO> interact $ unlines . map (++"!") . lines
hello
hello!
^CInterrupted.
Prelude System.IO>
精彩评论