我有一个制作人:
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 ()
?
答案 0 :(得分:1)
简答:
processMessage
很好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 有三种变体,runStateT
、evalStateT
和 execStateT
。我在此示例中选择了 execStateT :: StateT MyState IO () -> IO MyState
变体,但请根据您的情况选择您需要的任何一个。
main :: IO ()
main = do
st <- execStateT (runEffect $ for p processMessage) 0
putStrLn $ "End state: " <> show st