safe-freeze-0.2: Support for safely freezing multiple arrays in the ST monad.

MaintainerReiner Pope <>
Safe HaskellSafe-Infered




An indexed version of the ST monad with support for safely freezing multiple arrays. Compare to the usual ST monad, where the only support for safely freezing arrays is runSTUArray -- only one array may be frozen.

This version of the ST monad has two distinct stages of processing: the normal stage, and the freeze stage. Reading and writing are permitted in the normal stage; reading and freezing are permitted in the freeze stage. This policy ensures that no writes occur after the arrays have been frozen.

This ST is an indexed monad (see Control.Monad.Indexed) as well as a normal monad. That is, each monadic value will have an "ingoing" state thread as well as an "outgoing" state thread. These state threads are similar to the ST monad's state thread, except that they are now annotated with a stage name: either Normal or Freeze.


Stage names

data Normal s Source

data Freeze s Source

MonadST class

class IxMonad st => MonadST st whereSource


liftST :: ST s a -> STNormal st s aSource

For lifting any operations containing writes but no freezes.

liftRead :: ST s a -> STRead st s aSource

For lifting any operations containing reads but no writes or freezes.

liftUnsafeFreeze :: ST s a -> STFreeze st s aSource

For lifting an unsafeFreeze operation


MonadST (STT m) 

type STNormal st s a = st (Normal s) (Normal s) aSource

A computation containing some writes but no freezes: it starts | and ends in the Normal stage.

type STFreeze st s a = forall stg. st (stg s) (Freeze s) aSource

A computation containing some freezes but no writes: it starts in | any stage, but ends in the Freeze stage.

type STRead st s a = forall stg. st (stg s) (stg s) aSource

A computation containing only reads: it starts and ends in any stage, but does not change stage. (Note that there would be no loss of safety in allowing the stage to change, but it may result in ambiguous types, or extra type annotations being required.)

ST monad

runST :: (forall s. STT Identity (stg1 s) (stg2 s) a) -> aSource

ST transformer

data STT m s t a Source

An ST monad transformer. However, this is not a genuine monad transformer, as that would be unsafe (see To retain safety, it may only act as a monad transformer over the Identity and IO monads, enforced by the STTBase typeclass.

Defining STT as a monad transformer rather than just a monad allows ST arrays to be used in the IO monad, bringing safe freezing also to the IO monad.


IxMonad (STT m) 
IxFunctor (STT m) 
IxApplicative (STT m) 
IxPointed (STT m) 
MonadST (STT m) 
Monad (STT m s s) 
Functor (STT m s t) 
Applicative (STT m s s) 

class STTBase m whereSource


runSTT :: (forall s. STT m (stg1 s) (stg2 s) a) -> m aSource

Runs the monad

lift :: m a -> STT m (stg s) (stg s) aSource

A restricted analog of Control.Monad.Trans.lift.