unsafePerformIO to give warnings

Ian Lynagh igloo@earth.li
Fri, 21 Dec 2001 12:25:31 +0000


On Fri, Dec 21, 2001 at 10:21:06AM -0000, Simon Marlow wrote:
> 
> > 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.

Doh - I associate that with debugging and it never even occurred to me!

> > warnings interspersed?
> 
> It is possible to get warnings interspersed if you write something like
> 
> 	warn ("abc" ++ warn "foo" "def")

Ah, yes, OK, thanks.

> > 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.

Sorry, I meant "hugs and ghci only seem to print the warning the first
time I run the program", e.g. with

    module Main where

    import IOExts

    main :: IO()
    main = trace "foo" (putStrLn "bar")

in hugs:

    [...]
    Type :? for help
    Main> main
    foobar

    Main> main
    bar

    Main> main
    bar

    Main> main
    bar

and in ghci:

    Skipping  Main             ( q.lhs, ./q.o )
    Main> main
    foo
    bar
    Main> main
    bar
    Main> main
    bar
    Main> main
    bar
    Main> 


Thanks again
Ian