Home > Enterprise >  Using IO inside the ST monad and runSTUArray
Using IO inside the ST monad and runSTUArray

Time:12-21

I'm just starting to experiment with monad transformers so I may have missed something trivial. Anyway: how can I print from inside the ST monad?

Example code: I want to create code that is almost as fast as C, by reading and writing as quickly as possible to memory, with C-like for loops. I have an ST monad action that safely mutates an unboxed array that I run with runSTUArray.

My question is, how can I use IO actions inside the ST action? If it was a State monad action, I could use the StateT transformer to lift the IO actions to, but how is that done for the ST monad?

Example: ST. -- how can I print form inside the ST monad?

import Control.Monad.ST (ST)
import Data.Array.Base ( STUArray(STUArray), newArray, readArray, writeArray )
import Data.Array.ST (runSTUArray)
import Data.Array.Unboxed ( elems )
import Control.Monad (forM_)

test :: IO ()
test = print . elems $ runSTUArray action
  where
    action :: ST s (STUArray s Int Int)
    action = do
        arr <- newArray (1,10) 1
        forM_ [3..10] $ \i -> do
            -- liftIO . print $ "i is "    show i.   --- <--- How should I do this?
            x1 <- readArray arr (i-1)
            x2 <- readArray arr (i-2)
            writeArray arr i (x1 x2)
        return arr

Example: StateT, -- here it is possible to lift the print to use it inside the monad/

import Data.Array.IArray (listArray, (!), (//), elems)
import Data.Array (Array)
import Control.Monad.Trans.State.Strict (StateT (runStateT), get, put)
import Control.Monad.IO.Class (MonadIO(liftIO))
import Control.Monad (forM_)

test :: IO ()
test = do
    let n = listArray (1,10) [1..] :: Array Int Int
    (_,x) <- runStateT action n
    print $ elems x
    return ()

    where action = do
            forM_ [3..10] $ \i -> do
                x <- get
                liftIO . print $ "i is "    show i.  -- <--- here printing works fine
                put (x // [(i, x!(i-1)   x!(i-2))])

CodePudding user response:

You don't print from an ST action, you print from an IO action. Luckily for you, there are IOUArrays -- and they are even STUArrays under the hood, so there can be no fear of performance lost.

  • Related