Using Data.Machine, how can you put two ProcessTs together that change two different states?

Let's say I have a process that changes the underlying state, which is Int :

 p1 :: ProcessT (State Int) Int Int p1 = repeatedly $ do a <- await lift . modify $ (+a) yield a 

And another one that changes the base state, which is [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 write them as follows:

 p3 = source [1...6] ~> p1 ~ p2 

And run them like this:

 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 

The sentence p1 and p2 must have the same type of base state. In fact, a small experiment shows that p1 and p2 actually modify the base state of the same . How can I get around this?

+4
source share
1 answer

You can make a larger state and change each calculation to take the lens into a more complex state for the system.

 p1 :: (MonadState sm, Num a) => Lens' sa -> ProcessT maa p1 l = repeatedly $ do a <- await l += a yield a 

Then you just need to provide a larger composite state and appropriate lenses to manage all of this.

+3
source

Source: https://habr.com/ru/post/1494764/


All Articles