Desugaring ArrowLoop notation

Hello cafe, I was reading Stephen's Arrow Tutorial [1], where (among other things), a way to compute the running mean of a stream of integers using circular programming (ArrowLoop) is shown: mean5 :: Fractional a => Circuit a a mean5 = proc value -> do rec (lastTot, lastN) <- delay (0,0) -< (tot, n) let (tot, n) = (lastTot + value, lastN + 1) let mean = tot / n returnA -< mean To understand the example better I tried to convert the `rec do` notation to plain loop/(>>>) one (i.e. without syntactic sugar), but failed. So I ask: what's the sour version of `mean5`? -F [1] https://en.wikibooks.org/wiki/Haskell/Arrow_tutorial

mean5 :: Fractional a => Circuit a a mean5 = proc value -> do rec (lastTot, lastN) <- delay (0,0) -< (tot, n) let (tot, n) = (lastTot + value, lastN + 1) let mean = tot / n returnA -< mean
So I ask: what's the sour version of `mean5`?
The translation is very similar to the one for 'mfix', except that you need to account for the side channel in the input: mean5 = loop $ proc (value, ~(tot', n')) -> do (lastTot, lastN) <- delay (0,0) -< (tot', n') let (tot, n) = (lastTot + value, lastN + 1) id -< (tot / n, (tot, n)) You need the values 'tot' and 'n' to be in scope as input to the 'delay' action. To achieve that you literally just return them as the second output component, and 'loop' will feed them back as the second input component. That's how they get in scope for 'delay's input. This is not the exact way it's desugared (which is probably a lot uglier), but it's equivalent and should give you an intuition for how 'loop' works. I'm not entirely sure the lazy pattern is necessary or even possible. If it's possible, it's probably also necessary. Greets ertes

On Sat, Jan 28, 2017 at 03:07:48PM +0100, Ertugrul Söylemez wrote:
mean5 :: Fractional a => Circuit a a mean5 = proc value -> do rec (lastTot, lastN) <- delay (0,0) -< (tot, n) let (tot, n) = (lastTot + value, lastN + 1) let mean = tot / n returnA -< mean
So I ask: what's the sour version of `mean5`?
The translation is very similar to the one for 'mfix', except that you need to account for the side channel in the input:
mean5 = loop $ proc (value, ~(tot', n')) -> do (lastTot, lastN) <- delay (0,0) -< (tot', n') let (tot, n) = (lastTot + value, lastN + 1) id -< (tot / n, (tot, n))
Thank you, loop machinery is much more clearer now!
participants (2)
-
Ertugrul Söylemez
-
Francesco Ariis