"interact" behaves oddly if used interactively

Keith Wansbrough Keith.Wansbrough at cl.cam.ac.uk
Wed Oct 1 15:05:16 EDT 2003

> But looking at the two actions of interact:
> interact f = do
>     s <- getContents
>     putStr (f s)

(The Haskell report has two more actions, btw, setting nobuffering here)

> I would expect the first action to be finished before the second, (and I 


The magic here, in any case, is in getContents, which returns a list 
that is *lazily evaluated as needed* (Haskell report, page 98 (sec 
7.1)).  hGetContents does the same for an arbitrary handle.  This 
allows you to replicate the behaviour of Unix cat, ncat, grep etc, 
without having to code it explicitly.

For the use of laziness, consider

let fib = 0 : 1 : zipWith (+) fib (tail fib) in fib

and think what would happen if "let" was strict.  Programming in 
Haskell can be much more convenient than in strict languages, and 
laziness is assumed in lots of little ways throughout idiomatic Haskell 
code (I'm thinking of the liberal use of "where" and "let" bindings, 
for example).

> would not call it "interact" anymore after this discussion).

> Therefore, the "primitives" (getContents, putStr) behave "incorrect" to 
> my taste, (although the actual behaviour may be more desirable for 
> special other purposes.)

getContents behaves according to the specification in the standard, 
which is good enough for me.  So does putStr.

> Christian


--KW 8-)

More information about the Haskell mailing list