"interact" behaves oddly if used interactively

Simon Marlow simonmar at microsoft.com
Wed Oct 1 17:42:52 EDT 2003

[ taking this one to haskell-café... ]

> I still do not quite agree with Simon that 'interact' exposes anything
> but non-strictness. Non-strictness means that
>   map toUpper _|_ = _|_
>   map toUpper ('a':_|_) = ('A':_|_)
>   map toUpper ('a':'b':_|_) = ('A':'B':_|_)
> and 'interact (map toUpper)' is a great way to experience 
> this property.
> However, you can also experience the property without 'interact',
> evaluating expressions like
>   take 2 (map toUpper ('a':'b':undefined))

Certainly you can observe non-strictness, that's not the point.  The point is that you can also observe more than just non-strictness using interact, and I don't think that is desirable.  For example:

  interact (\xs -> let z = length xs in "Hello World\n")

Now, Haskell is a pure language, so it shouldn't matter whether the implementation evaluates z or not, as long as it is careful not to violate the non-strict semantics by turning a terminating program into a non-terminating one.  A parallel Haskell implementation might happily spawn off another thread to evaluate z for example.  An optimistic implementation might evaluate z for a fixed amount of time before continuing with the main thread of evaluation.

BUT in the presence of lazy I/O this simply isn't true any more.  Why?  Because z is not pure; evaluating it has a side-effect.  And yet it has type Int.  Am I the only one who thinks this is wrong?


More information about the Haskell-Cafe mailing list