[Haskell-cafe] Re: Question about IO, interact functions,

Ertugrul Soeylemez es at ertes.de
Tue May 19 14:56:22 EDT 2009

David Leimbach <leimy2k at gmail.com> wrote:

> 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

  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.


nightmare = unsafePerformIO (getWrongWife >>= sex)

More information about the Haskell-Cafe mailing list