Reactive Banana 1.0.0 - 为什么这个旧代码会被破坏?

Reactive Banana 1.0.0 - Why is this old code breaking?

这是曾经有效的代码(我希望适当截断)

makeNetworkDescription :: forall t . Frameworks t => Parameters -> Moment t ()
makeNetworkDescription params = do
  eInput <- fromAddHandler (input params)
  eTick <- fromAddHandler (tick params)
  ..
let
    bResourceMap :: Behavior t ResourceMap
    bResourceMap = accumB initRmap $
      adjustMarket <$>
      bMarketRolls <@
      eTick

但是现在类型变了。
我们有:
makeNetworkDescription :: Parameters -> MomentIO ()accumB :: MonadMoment m => a -> Event (a -> a) -> m (Behavior a)

假设我将 bResourceMap 的定义更改为

bResourceMap :: Behavior ResourceMap
bResourceMap = accumB initRmap $
               adjustMarket   <$>
               bMarketRolls   <@
               eTick

accumB 的定义略有不同,但让我们看看会发生什么。

ghc报错

Couldn't match type ‘Behavior ResourceMap’ with ‘ResourceMap’
Expected type: Behavior ResourceMap
  Actual type: Behavior (Behavior ResourceMap)

是的,由于 accumB 的类型,行为需要在 MonadMoment 的上下文中。查看 MonadMoment 我发现两个实例

instance MonadMoment Moment where liftMoment = id
instance MonadMoment MomentIO where liftMoment = MIO . unM

那么为什么实际类型解析为 Behavior (Behavior ResourceMap),外部类型必须是 MonadMoment,这不匹配。

我需要有关如何解决此类问题的建议,我的所有 Behavior 定义都会遇到这种问题。

调整代码以适应 accumB 的新类型应该只使用单子绑定而不是 let 表达式来定义 bResourceMap:

bResourceMap <- accumB initRmap (adjustMarket <$> bMarketRolls <@ eTick)

您引用的类型错误似乎与此无关。我的猜测是 initRmap 被意外地从 ResourceMap 更改为 Behavior ResourceMap,导致类型不匹配。