【问题标题】:Using Data.Machine, how can you compose two ProcessT together that modifies two different states?使用 Data.Machine,如何将两个 ProcessT 组合在一起来修改两个不同的状态?
【发布时间】:2013-08-01 14:41:12
【问题描述】:

假设我有一个修改底层状态的进程 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 实际上正在修改相同的底层状态。我该如何回避这个?

【问题讨论】:

    标签: haskell coroutine transducer-machines


    【解决方案1】:

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

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

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

    【讨论】:

    • 你也可以提供一个mapProcessT 函数,这样人们就可以很容易地进行缩放。
    • 我很乐意通过补丁添加它。 ;)
    • 实际上,现在我想起来了,我认为它已经在fit 中了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    • 1970-01-01
    • 2016-07-20
    • 1970-01-01
    • 2011-07-22
    相关资源
    最近更新 更多