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

时间:2015-10-20 14:03:25

标签: haskell frp reactive-banana

这里的代码曾经工作过(我希望适当地截断)

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定义。

1 个答案:

答案 0 :(得分:5)

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

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

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