I have a function with a type Map Int String -> Proxy () a () Void IO b
. Right now it await
s, does whatever with the value it got, and then re-calls itself. I'd like to change it to use State (Map Int String)
instead of having that passed as an argument, so I can just use forever
and don't need to have every branch remember to recurse. I get that I need to use StateT
to combine State
with another monad, but I don't understand where in that type signature the StateT
belongs, or whether or not I need to lift
functions like get
. What is the correct type for a function that is both a State (Map Int String)
and a Proxy () a () Void IO b
?
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With