I was following the same article along, trying to translate it to Netwire 5.0 as well. This was indeed a bit of a sticky point. I ended up creating a new integralWith'
function similar in design to the integralWith
but which takes as input a single value and produces two values.
integralWith' ::
(Fractional a, HasTime t s)
=> (a -> (a, o)) -- Function for potentially limiting the integration
-- and producing a secondary output.
-> a -- Integration constant (aka start value).
-> Wire s e m a (a, o)
integralWith' correct = loop
where
loop x' =
mkPure $ \ds dx ->
let dt = realToFrac (dtime ds)
(x,b) = correct (x' + dt*dx)
in x' `seq` (Right (x', b), loop x)
This is almost directly copied from http://hackage.haskell.org/package/netwire-5.0.0/docs/src/FRP-Netwire-Move.html#integralWith, all I did was fiddle with the types to get it to work.
My position
function ended up looking like this.
position :: (Monad m, HasTime t s) => Wire s e m Double (Double, Bool)
position = integralWith' clamp 0
where
clamp p | p < 0 || p > 150 = (max 1 (min 149 p), True)
| otherwise = (p, False)
As I am just getting into FRP and Haskell myself, I'm not sure if something like this already exists in the netwire library or not, or if it is even generally useful, or if there is a simpler way that I have not yet seen.