Reactive Banana 1.0.0 - Why is this old code breaking?
Asked Answered
D

1

6

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.

Detritus answered 20/10, 2015 at 14:3 Comment(2)
just curious: is this a real or hobby project?Balas
It's real, but not a game qua game. It's a game serving a purpose other than being just a game.Detritus
O
4

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.

Oversubscribe answered 20/10, 2015 at 17:8 Comment(3)
I've tried that but then other bindings fall out of scope. I'm thinking I need to add RecursiveDo to prevent that.Detritus
@MichaelLitchard Indeed -- the changes mean you will need MonadFix/RecursiveDo in some form for mutually recursive definitions involving behaviours defined with acummB/stepper.Oversubscribe
For future haskellers - the key is to use mdo instead of do. Syntactic sugar for rec and fix.Detritus

© 2022 - 2024 — McMap. All rights reserved.