簡體   English   中英

使用 State 的管道“運行”

[英]Pipes `run` with State

我有一個制片人:

p:: Producer Message IO r

我可以使用以下方法處理所有消息:

runEffect $ for p processMessage

在哪里

processMessage:: Message -> Effect IO ()

如何使用以下方法實現有狀態處理:

processMessage:: Message -> Effect (StateT MyState IO) () ?

簡短的回答:

  1. 修改您的生產者以使其對其運行的 monad 不可知
  2. 你的processMessage很好
  3. runEffect返回StateT MyState IO () ,你需要評估它

用一個虛擬例子來回答更長的問題:

您的生產者被鎖定在IO monad 中,您需要將其修改為在MonadIO m或顯式 state monad 中。

import Control.Monad.State
import Pipes

type Message = Int

p :: MonadIO m => Producer Message m ()
p = each [1..10]

您的processMessage的簽名已經很好了。 我正在遵循您的簽名並添加一些簡單的邏輯來練習 IO 和 State 功能

processMessage :: Message -> Effect (StateT MyState IO) ()
processMessage msg = do
  modify (+ msg)
  liftIO (print msg)

然后是最后一步。 runEffect:: Monad m => Effect m r -> m r , if you substitute the m with a concrete type, this ends up being runEffect:: Effect (StateT MyState IO) () -> StateT MyState IO () , meaning that您將剩下 state monad 仍然需要執行。 執行 state monad、 runStateTevalStateTexecStateT有三種變體。 在本例中,我選擇了execStateT:: StateT MyState IO () -> IO MyState變體,但在您的情況下選擇您需要的任何一個。

main :: IO ()
main = do
  st <- execStateT (runEffect $ for p processMessage) 0
  putStrLn $ "End state: " <> show st

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM