haskellfrpreactive-banana

Reactive Banana 1.0.0 - Why is this old code breaking?


Here's code that used to work (truncated appropriately I hope)

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

But now the types have changed.
we have:
makeNetworkDescription :: Parameters -> MomentIO () and accumB :: MonadMoment m => a -> Event (a -> a) -> m (Behavior a)

say I change the definition of bResourceMap to

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

slightly off from the accumB definition, but let's see what happens.

ghc gives an error

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

Right, because of the type of accumB the behavior needs to be within the context of a MonadMoment. Having a look at MonadMoment I find two instances

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

So why did the actual type resolve to Behavior (Behavior ResourceMap), the outer type has to be a MonadMoment, which doesn't match.

I'd like advice on how to resolve this type of problem, it happens with all my Behavior definitions.


Solution

  • Adjusting your code to fit the new type of accumB should only take using a monadic bind rather than a let expression to define bResourceMap:

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

    The type error you quote seems unrelated. My guess would be that initRmap was accidentally changed from being a ResourceMap to a Behavior ResourceMap, leading to the the type mismatch.