[英]State monad: How to `print` intermediate value in Haskell
I'm new in haskell and I have following code 我是haskell的新手,我有以下代码
module StateTest where
import Control.Monad.State.Lazy
tick :: State Int Int
tick = do n <- get
put (n+1)
return n
plusOne :: Int -> Int
plusOne = execState tick
main = print $ plusOne 1
And I want to print state value after put (n+1)
and continue computation like this 我想在put (n+1)
之后打印状态值并继续这样计算
tick = do n <- get
put (n+1)
print
return n
How whole code will look following to this? 整个代码如何看待这个?
If you want to run IO actions within a state computation you can change the type of tick
to return a StateT Int IO Int
and use liftIO
. 如果要在状态计算中运行IO操作,可以更改tick
的类型以返回StateT Int IO Int
并使用liftIO
。 Then you can run it using execStateT
: 然后你可以使用execStateT
运行它:
import Control.Monad.State.Lazy
import Control.Monad.IO.Class (liftIO)
tick :: StateT Int IO Int
tick = do n <- get
put (n+1)
liftIO $ print (n+1)
return n
plusOne :: Int -> IO Int
plusOne = execStateT tick
main = plusOne 1 >> pure ()
Another option, since you would have to use IO
anyway to print a value in the intermediate state, would be to use IORef
. 另一个选择,因为你必须使用IO
来打印中间状态的值,将使用IORef
。 It's a container that has an updateable value. 它是一个具有可更新值的容器。
module Main where
import Data.IORef
tick :: IORef Int -> IO (IORef Int)
tick ref = do
modifyIORef' ref (+1)
-- you can also print here since it is IO
pure ref
main :: IO ()
main = do
counter <- newIORef 0
tick counter
v2 <- readIORef counter
print v2
tick counter
v2 <- readIORef counter
print v2
You can then clean it up with ReaderT
. 然后,您可以使用ReaderT
清理它。
module Main where
import Data.IORef
import Control.Monad.Reader
readerTick :: ReaderT (IORef Int) IO ()
readerTick = do
ref <- ask
-- can also print here with liftIO $ print ...
liftIO $ modifyIORef' ref (+1)
main :: IO ()
main = do
counter <- newIORef 0
runReaderT readerTick counter
v1 <- readIORef counter
print v1
runReaderT readerTick counter
v2 <- readIORef counter
print v2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.