2015-10-20 76 views
6

这里的代码,用来工作(截断适当希望)反应香蕉1.0.0 - 为什么这个旧的代码破坏?

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

+0

只是好奇:这是一个真正的或爱好项目? –

+0

这是真实的,但不是一款游戏。这是一个游戏,除了只是一个游戏之外,还有其他目的。 –

回答

5

调整你的代码以适应新的类型的accumB应该只使用一元绑定,而不是let表达式来定义bResourceMap采取:

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

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

+0

我试过,但其他绑定掉出范围。我想我需要添加RecursiveDo来防止这种情况。 –

+1

@MichaelLitchard的确 - 这些变化意味着您需要'MonadFix' /'RecursiveDo'以某种形式进行相互递归定义,这涉及到使用'acummB' /'stepper'定义的行为。 – duplode

+0

对于未来的haskellers--关键是使用mdo而不是do。用于rec和fix的语法糖。 –