unsafePerformIO to give warnings

Simon Marlow simonmar@microsoft.com
Fri, 21 Dec 2001 10:21:06 -0000

> If I want to give warnings when doing something and I don't care too
> much about the order they appear in, can I use this?
>     foo x =3D if success x then Just x
>                          else warn "Working out x went wrong" Nothing
>     warn :: String -> a -> a
>     warn s x =3D unsafePerformIO (hPutStrLn stderr s) `seq` x

This is what IOExts.trace is for, BTW.

> The hslibs docs say
>     If the I/O computation wrapped in unsafePerformIO performs side
>     effects, then the relative order in which those side effects take
>     place (relative to the main I/O trunk, or other calls to
>     unsafePerformIO) is indeterminate.
> but it's not entirely clear on whether or not I could end up with 2
> warnings interspersed?

It is possible to get warnings interspersed if you write something like

	warn ("abc" ++ warn "foo" "def")

> And is it guaranteed that the warnings will be printed at some point?

All that is guaranteed is that if an expression 'warn a b' is evaluated
then 'a' will be evaluated to a String and then printed.

> hugs and ghci only seem to print the first warning, but ISTR similar
> problems happen with threads and got the impression that they were in
> the wrong.

Are you sure that laziness and/or optimisation aren't to blame for only
getting a single warning?  Given that you say Hugs also produces the
same result, it sounds like a laziness issue.