Note: Proxy () a () Void = Consumer a
, so I will refer to it as a Consumer
for this answer.
The simple way is to put your StateT
monad transformer layer outside of the Consumer
layer and then run it immediately. Here is an example:
import Control.Monad (forever)
import Control.Monad.Trans.State.Strict
import Pipes
example :: (Show a) => Consumer a IO r
example = flip evalStateT 0 $ forever $ do
-- Inside here we are using `StateT Int (Consumer a IO) r`
a <- lift await
n <- get
lift $ lift $ putStrLn $ "Received value #" ++ show n ++ ": " ++ show a
put (n + 1)
... and this is how it behaves in action:
>>> runEffect $ each ["Test", "ABC"] >-> example
Received value #0: "Test"
Received value #1: "ABC"