> 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