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 = if success x then Just x else warn "Working out x went wrong" Nothing
warn :: String -> a -> a warn s x = 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. Cheers, Simon