简体   繁体   English

State monad:如何在Haskell中“打印”中间值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM