
I propose to change the internal representation of the strict ST monad to newtype ST s a = ST (forall r. (a -> r) -> r) which is a generalization of the new representation of IO monad: newtype IO a = IO ((a -> IOResult) -> IOResult) This will enable simple conversion between the monads: runST :: (forall s. ST s a) -> a runST m = let ST f = m in f id stToIO :: ST RealWorld a -> IO a stToIO (ST f) = IO f and will allow us to reuse several IO primitives as ST primitives, e.g. primitive thenStrictST "primbindIO" :: ST s a -> (a -> ST s b) -> ST s b primitive returnST "primretIO" :: a -> ST s a primitive newSTRef "newRef" :: a -> ST s (STRef s a) primitive primNewArr "IONewArr" :: (a,a) -> Int -> b -> ST s (STArray s a b) dispensing with stmonad.c. For the lazy ST monad, I plan to use newtype ST s a = ST (State s -> (a, State s)) type State s = () lazyToStrictST :: ST s a -> ST.ST s a lazyToStrictST (ST m) = ST.ST (\k -> case m () of (a,()) -> k a) strictToLazyST :: ST.ST s a -> ST s a strictToLazyST (ST.ST m) = ST (\() -> m delay) where delay :: a -> (a, State s) delay a = (a,()) and use the fptools library code, which uses these to lift all the operations from the strict monad. Then Hugs will have the same interface to these monads as GHC, with more flexible control over laziness than before.
participants (1)
-
Ross Paterson