Let's say I have a process that modifies an underlying state that is an Int
:
p1 :: ProcessT (State Int) Int Int
p1 = repeatedly $ do
a <- await
lift . modify $ (+a)
yield a
And another that modifies an underlying state that is an [Int]
:
p2 :: ProcessT (State [Int]) Int Bool
p2 = repeatedly $ do
a <- await
lift . modify $ (++[a])
as <- get
if length as > 3 then yield True else yield False
I want to compose them this way:
p3 = source [1...6] ~> p1 ~ p2
And run them like:
flip runState 0 . flip runState [] . runT $ p3
But I get this error:
Couldn't match expected type `Int' with actual type `[Int]'
Expected type: ProcessT (State Int) Int c0
Actual type: ProcessT (State [Int]) Int Bool
In the second argument of `(~>)', namely `p2'
In the expression: source [1 .. 6] ~> p1 ~> p2
Suggesting p1 and p2 should have the same type of underlying state. In fact, a little experiment shows that p1 and p2 are in fact modifying the same underlying state. How can I sidestep this?
You can make a bigger state and modify each computation to take a lens into a larger composite state for the system.
You then just need to supply the larger composite state and appropriate lenses to drive the whole thing.