On Wed, Oct 04, 2000 at 01:05:10PM +0200, Marcin 'Qrczak' Kowalczyk wrote:
: On Wed, 4 Oct 2000, Ross Paterson wrote:
:
: > The library documentation says
: >
: > stToIO :: ST s a -> IO a
: >
: > but PrelIOBase says
: >
: > stToIO :: ST RealWorld a -> IO a
:
: AFAIR it's a different stToIO than one exported by the end-user module
: (IOExts or ST). Sorry, can't check it from here.
No, ST re-exports it from PrelIOBase.
: > The documented type would be unsafe (as it is in Classic Hugs), so it
: > seems necessary to mention the real world in the documentation.
:
: Why is it unsafe? IMHO it is safe.
The following is accepted by hugs -98:
> import ST
> data Var v = Var { readVar :: IO v, writeVar :: v -> IO () }
> newVar :: v -> Var v
> newVar v = runST (do
> r <- newSTRef v
> return (Var {
> readVar = stToIO (readSTRef r),
> writeVar = \v' -> stToIO (writeSTRef r v')
> })
> )
> test :: Var Int -> Var Int -> IO ()
> test v1 v2 = do
> writeVar v1 3
> writeVar v2 4
> x <- readVar v1
> y <- readVar v2
> print x
> print y
> main = let v = newVar 0 in do
> test v v
> test (newVar 0) (newVar 0)
but the two tests do different things, breaking substitution.
GHC instantiates the state type variable to RealWorld, and then
complains
Inferred type is less polymorphic than expected
Quantified type variable `s' is unified with `RealWorld'
Signature type: forall s. ST s a
Type to generalise: ST RealWorld (Var v)
I think GHC is right and the library documentation wrong.