What I mean by first-order constraint
First, I'll explain what I mean by first-order constraint on arrows: Due to the way arrows desugar, you cannot use a locally bound name where an arrow command is expected in the arrow do-notation.
Here is an example to illustrate:
proc x -> f -< x + 1 desugars to arr (\x -> x + 1) >>> f and similarly proc x -> g x -< () would desugar to arr (\x -> ()) >>> g x, where the second x is a free variable. The GHC user guide explains this and says that when your arrow is also a monad you may make an instance of ArrowApply and use app to get around this. Something like, proc x -> g x -<< () becomes arr (\x -> (g x, ())) >>> app.
My Question
Yampa defines the accumHold function with this type: a -> SF (Event (a -> a)) a.
Due to this first-order limitation of arrows, I'm struggling to write the following function:
accumHoldNoiseR :: (RandomGen g, Random a) => (a,a) -> g -> SF (Event (a -> a)) a
accumHoldNoiseR r g = proc f -> do
n <- noiseR r g -< ()
accumHold n -< f
The definition above doesn't work because n is not in scope after desugaring.
Or, similarly this function, where the first part of the pair to SF is meant to be the initial value passed to accumHold
accumHold' :: SF (a,Event (a -> a)) -> a
accumHold' = ...
Is there some combinator or trick that I'm missing? Or is it not possible to write these definitions without an ArrowApply instance?
tl;dr: Is it possible to define accumHoldNoiseR :: (RandomGen g, Random a) => (a,a) -> g -> SF (Event (a -> a)) a or accumHold' :: SF (a,Event (a -> a)) -> a in yampa?
Note: There is no instance of ArrowApply for SF. My understanding is that it doesn't make sense to define one either. See "Programming with Arrows" for details.