4

假设我有一个修改底层状态的过程Int

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

另一个修改底层状态是[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

我想这样组合它们:

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

并像这样运行它们:

flip runState 0 . flip runState [] . runT $ p3

但我得到这个错误:

   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

建议 p1 和 p2 应该具有相同类型的基础状态。事实上,一个小实验表明 p1 和 p2 实际上正在修改相同的底层状态。我怎么能回避这个?

4

1 回答 1

4

您可以创建更大的状态并修改每个计算以使镜头进入系统的更大复合状态。

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

然后你只需要提供更大的复合状态和适当的镜头来驱动整个事情。

于 2013-08-01T15:26:53.450 回答