Question about IO, interact functions,

main = interact (unlines . lines) This *appears* to somewhat reliably get me functionality that looks like take a line of input, and print it out. Is this behavior something I can rely on working? I like the idea that lines can pull lines lazily from "getContents" which lazily consume the input. But I'm concerned that relying on a pure function like "unlines . lines" to sequence IO is a bit too implicit in nature. I really like the idea of doing things through functions like Interact in that they appear to allow me to keep most of my code pure, but if I can't get the IO sequencing I want to be guaranteed to work, I suppose I'll have to dive back into "imperative IO" land that I get from the IO Monad. Should I feel guilty for doing so? :-) Dave

2009/05/19 David Leimbach
...I'm concerned that relying on a pure function like "unlines . lines" to sequence IO is a bit too implicit in nature.
You aren't relying on `unlines . lines` to do the sequencing; you're relying on them to process a string. That the characters of the string come in order has everything to do with `getContents`, which is trustworthy. -- Jason Dusek

David Leimbach
main = interact (unlines . lines) This *appears* to somewhat reliably get me functionality that looks like take a line of input, and print it out.
Is this behavior something I can rely on working?
I like the idea that lines can pull lines lazily from "getContents" which lazily consume the input. But I'm concerned that relying on a pure function like "unlines . lines" to sequence IO is a bit too implicit in nature.
As Jason pointed out, you're relying on getContents. Your little function composition "unlines . lines" will do nothing at all in most cases, although in some configurations it may replace line feed representations. What you're really relying on is the buffering method used by 'stdin' and 'stdout'. If you want to make sure, use the following: import System.IO main :: IO () main = do mapM_ (`hSetBuffering` LineBuffering) [stdin, stdout] iterate f
I really like the idea of doing things through functions like Interact in that they appear to allow me to keep most of my code pure, but if I can't get the IO sequencing I want to be guaranteed to work, I suppose I'll have to dive back into "imperative IO" land that I get from the IO Monad.
Should I feel guilty for doing so? :-)
Not always. Especially when writing concurrent code for things like servers, I usually write highly imperative code, using functional constructs where appropriate. Being a functional language of course makes Haskell much more powerful and expressive, but it has lots of more advantages like an amazing concurrency system. =) Note: 'Iterate' would be a type, a class or a module. Functions (and type variables) _must_ be written in lower-case in Haskell. Greets, Ertugrul. -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/
participants (3)
-
David Leimbach
-
Ertugrul Soeylemez
-
Jason Dusek