管道“运行”与状态

时间:2021-02-17 00:14:44

标签: haskell haskell-pipes

我有一个制作人:

Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: Center( child: Column( children: [ Opacity( opacity: 0.25, child: Container( child: Image.asset('assets/images/logo.png'), margin: EdgeInsets.only(top: 100), width: 75, ), ), Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text('Please enter your first name:'), TextButton(onPressed: () {}, child: Text('Submit')) ], ) ], ), ), );

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

p :: Producer Message IO r

哪里

runEffect $ for p processMessage

如何使用以下内容实现有状态处理:

processMessage :: Message -> Effect IO () ?

1 个答案:

答案 0 :(得分:1)

简答:

  1. 修改你的生产者,使其对运行的 monad 不可知
  2. 你的processMessage很好
  3. runEffect 返回 StateT MyState IO (),您需要对其进行评估

用一个虚拟示例给出更长的答案:

您的生产者被锁定在 IO monad 中,您需要将其修改为处于 MonadIO m 或显式状态的 monad。

import Control.Monad.State
import Pipes

type Message = Int

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

您的 processMessage 的签名已经没问题了。我正在关注您的签名并添加一些简单的逻辑来执行 IO 和状态功能

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

然后是最后一步。 runEffect :: Monad m => Effect m r -> m r,如果你用具体类型替换 m,这最终是 runEffect :: Effect (StateT MyState IO) () -> StateT MyState IO (),这意味着你将留下仍需要执行的 state monad。执行状态 monad 有三种变体,runStateTevalStateTexecStateT。我在此示例中选择了 execStateT :: StateT MyState IO () -> IO MyState 变体,但请根据您的情况选择您需要的任何一个。

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