"interact" behaves oddly if used interactively
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