I'm trying to understand FRP and Netwire. My best source of practical knowledge is this post, however it's a bit outdated, as it's written in Netwire 4, and I'm using version 5.0. I want to have player controlled square, that bounces off screen edges.
Based on that post I have this:
acceleration :: (Monad m, Monoid e) => Wire s e m (Set SDL.Keysym) Double
acceleration = pure (-80) . when (keyDown SDL.SDLK_LEFT)
<|> pure 80 . when (keyDown SDL.SDLK_RIGHT)
<|> pure 0
velocity :: (Monad m, HasTime t s, Monoid e) => Wire s e m (Double, Bool) Double
velocity = integralWith limit 0
where limit collision v = let newV = if collision then -v else v in clampMax maxV newV
challenge2 :: (MonadFix m, HasTime t s) => Wire s () m (Set SDL.Keysym) Double
challenge2 = proc keysDown -> do
a <- acceleration -< keysDown
rec v <- velocity -< (a, colls)
(pos, colls) <- position -< v
returnA -< pos
position :: (Monad m, HasTime t s, Monoid e) => Wire s e m Double (Double, Bool)
position = what to put here?
I want position wire to integrate velocity, correct the position to stay within bounds of the screen and produce Bool indicating that collision occurred. Linked article uses accumT, which, in current version of Netwire, is (AFAIK) gone. And it's not too pretty - integrating by hand when there is a wire for that... I know, that I can limit position using integralWith, but it can't produce anything more than a Fractional. I tried like this:
position = mkSF_ bounds . integral 0
where bounds pos = if trace (show pos) pos > 150 then (149, True) else if pos < 0 then (1, True) else (pos, False)
And forgive me that ;). Now I know that there is an internal state in integral wire, which I do not modify this way.
So what is the 'correct way' to achieve what I want?