在 ST monad 和 runSTUArray 中使用 IO
Using IO inside the ST monad and runSTUArray
我刚开始尝试使用 monad 转换器,所以我可能漏掉了一些微不足道的东西。无论如何:如何从 ST monad 内部打印?
示例代码:我想创建几乎与 C 一样快的代码,通过尽可能快地读写内存,使用类似 C 的 for 循环。我有一个 ST
monad 动作,可以安全地改变一个未装箱的数组,我 运行 和 runSTUArray
.
我的问题是,如何在 ST
动作中使用 IO
动作?如果它是一个 State
monad 动作,我可以使用 StateT
转换器将 IO
动作提升到,但是 ST
monad 是怎么做到的?
示例:ST。 -- 如何在 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
示例:StateT,-- 这里可以提升 print
以在 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))])
我刚开始尝试使用 monad 转换器,所以我可能漏掉了一些微不足道的东西。无论如何:如何从 ST monad 内部打印?
示例代码:我想创建几乎与 C 一样快的代码,通过尽可能快地读写内存,使用类似 C 的 for 循环。我有一个 ST
monad 动作,可以安全地改变一个未装箱的数组,我 运行 和 runSTUArray
.
我的问题是,如何在 ST
动作中使用 IO
动作?如果它是一个 State
monad 动作,我可以使用 StateT
转换器将 IO
动作提升到,但是 ST
monad 是怎么做到的?
示例:ST。 -- 如何在 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
示例:StateT,-- 这里可以提升 print
以在 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))])