I have a producer:
p :: Producer Message IO r.
I can process all messages using:
runEffect $ for p processMessage
where
processMessage :: Message -> Effect IO ().
How can I implement stateful processing using something like:
processMessage :: Message -> Effect (StateT MyState IO) () ?
Short answer:
processMessageis finerunEffectreturnsStateT MyState IO (), you need to evaluate itLonger answer with a dummy example:
Your producer is locked into the
IOmonad, you need to modify it to be either inMonadIO mor in the explicit state monad.The signature of your
processMessageis already fine. I'm following your signature and adding some simple logic to exercise the IO and State functionalityThen the final step.
runEffect :: Monad m => Effect m r -> m r, if you substitute themwith a concrete type, this ends up beingrunEffect :: Effect (StateT MyState IO) () -> StateT MyState IO (), meaning that you'll be left with the state monad which still needs to be executed. There's three variants for executing the state monad,runStateT,evalStateTandexecStateT. I choseexecStateT :: StateT MyState IO () -> IO MyStatevariant in this example, but choose whichever you need in your case.