> My intuition says that none of the side-effects in my 
> implementation are 
> visible from the abstract level of the module.  However, the use of 
> unsafePerformIO certainly modifies the behaviour of the 
> module.  For example, 
> the following definitions at the beginning of a GHCi session 
> on the attached 
> code lead to the subsequent behaviour:
> 
> 
> foo1 <- return (unsafePerformIO (mkAtom "foo"))
> foo2 <- return (unsafePerformIO (mkAtom "foo"))
> bar  <- return (unsafePerformIO (mkAtom "bar"))
> safefoo1 <- mkAtom "foo"
> safefoo2 <- mkAtom "foo"
> safebar  <- mkAtom "bar"
> list <- return [safefoo1, safefoo2, safebar, foo1, foo2, bar]

These uses of unsafePerformIO really *are* unsafe though :-)

Your implementation of mkAtom seems to be similar the the StableName
library, in that it has the property that if

        mkAtom e == mkAtom e', then e == e'

but the reverse isn't necessarily true (it may or may not be true).
Which is why mkAtom has to be in the IO monad: it has observable
non-determinism.

FastString works differently: it guarantees that both

        mkFastString s == mkFastString s'  =>   s == s'
        s == s'  =>  mkFastString s == mkFastString s'

hold.  So it is safe for mkFastString to be a pure non-I/O function,
because it doesn't have any observable non-deterministic behaviour.

Cheers,
        Simon

_______________________________________________
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Reply via email to