Hi all,
This e-mail is about two things.
===========================================================
The first is the definition of "unsafeIOtoST" in ST.hs.
Currently the definition is:
unsafeIOtoST :: IO a -> ST s a
unsafeIOtoST = returnST . unsafePerformIO
I think the following definition makes more sense:
unsafeIOtoST :: IO a -> ST s a
unsafeIOtoST io =
unsafePerformIO $
do a <- io
return (returnST a)
This is because one probably wants to have all side effects
coming from IO at exactly that spot in the ST computation
(otherwise it wouldn't make any sense to lift it into ST).
I am thinking of something like this:
do ...
unsafeIOtoST (writeIORef ref "cow")
...
This does not make any sense with the first definition.
===========================================================
And second, I think I found a bug in the implementation of
the strict ST monad. I am not sure, but I did the following:
1. I started with an IO computation only using
IORef's that I wanted to make pure. Everything worked
correctly.
2. I changed all IO's to (ST s)'s. I changed all
IORef's to STRef's. I added a big runST around my
function. Now I got incorrect results.
3. I spent lots of time debugging.
4. I made my own module MyST.hs, where I implement
ST and STRef using IO and IORef (see attachment).
5. I imported MyST instead of ST. Now everything works
again.
My question is: is this behavior possible with a correct
implementation of the strict ST monad?
===========================================================
Regards,
Koen.
--
Koen Claessen http://www.cs.chalmers.se/~koen
phone:+46-31-772 5424 e-mail:[EMAIL PROTECTED]
-----------------------------------------------------
Chalmers University of Technology, Gothenburg, Sweden
===========================================================
module MyST
( ST
, STRef
, newSTRef
, readSTRef
, writeSTRef
, runST
)
where
import IOExts
( IORef
, newIORef
, readIORef
, writeIORef
, unsafePerformIO
)
newtype ST s a
= ST (IO a)
unST :: ST s a -> IO a
unST (ST io) = io
instance Functor (ST s) where
fmap f (ST io) = ST (fmap f io)
instance Monad (ST s) where
return a = ST (return a)
ST io >>= k = ST (do a <- io ; unST (k a))
newtype STRef s a
= STRef (IORef a)
instance Eq (STRef s a) where
STRef r1 == STRef r2 = r1 == r2
newSTRef :: a -> ST s (STRef s a)
newSTRef a = ST (STRef `fmap` newIORef a)
readSTRef :: STRef s a -> ST s a
readSTRef (STRef r) = ST (readIORef r)
writeSTRef :: STRef s a -> a -> ST s ()
writeSTRef (STRef r) a = ST (writeIORef r a)
runST :: (forall s . ST s a) -> a
runST st = unsafePerformIO (unST st)