【问题标题】:Reactive Banana 1.0.0 - Why is this old code breaking?Reactive Banana 1.0.0 - 为什么这个旧代码会破坏?
【发布时间】:2016-01-19 05:50:04
【问题描述】:

这是过去可以工作的代码(我希望适当截断)

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 -&gt; MomentIO ()accumB :: MonadMoment m =&gt; a -&gt; Event (a -&gt; a) -&gt; 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 定义都会发生这种问题。

【问题讨论】:

  • 只是好奇:这是一个真实的项目还是爱好项目?
  • 这是真的,但不是游戏。这是一款服务于其他目的的游戏,而不仅仅是一款游戏。

标签: haskell frp reactive-banana


【解决方案1】:

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

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

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

【讨论】:

  • 我已经尝试过了,但是其他绑定超出了范围。我想我需要添加 RecursiveDo 来防止这种情况发生。
  • @MichaelLitchard 确实——这些变化意味着您将需要某种形式的 MonadFix/RecursiveDo 来进行相互递归定义,其中涉及使用 acummB/stepper 定义的行为。
  • 对于未来的haskellers - 关键是使用mdo而不是do。 rec 和 fix 的语法糖。
猜你喜欢
  • 2012-10-08
  • 2021-08-15
  • 2021-05-27
  • 1970-01-01
  • 1970-01-01
  • 2011-09-27
  • 1970-01-01
  • 2012-08-09
  • 2016-08-16
相关资源
最近更新 更多