这是曾经工作的代码(希望能被适当地截断)

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的方式仅应使用单子(monad)绑定(bind)而不是let表达式来定义bResourceMap:

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

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

08-26 18:52