
I'm deriving an FRP implementation based on the ideas presented in the Yampa Arcade paper (http://www.haskell.org/yale/papers/haskell-workshop03/) to improve my understanding of arrows, but I have a couple of questions. I'm using the following declaration for SF:
type DTime = Double newtype SF a b = SF { runSF :: DTime -> a -> (b, SF a b) }
which I make an arrow in the obvious way:
instance Arrow SF where arr f = SF sf where sf dt b = (f b, SF sf) bc >>> cd = SF sf where sf dt b = (d, bc' >>> cd') where (c, bc') = runSF bc dt b (d, cd') = runSF cd dt c first bc = SF sf where sf dt ~(b,d) = ((c,d), sfFirst bc') where (c, bc') = runSF bc dt b
One question I had was about the implementation of "first". Is it important that the pair match be lazy? Or is it safe to make it strict? What are the advantages and disadvantages of each choice? My other question had to do with ArrowChoice.
instance ArrowChoice SF where left bc = SF sf where sf dt (Right d) = (Right d, left bc) sf dt (Left b) = (Left c, left bc') where (c, bc') = runSF bc dt b
What happens to the dt in the "Right d" case? It seems to be invisible to the inner signal function. Is this the right thing to do? I have an alternate implementation which does the following:
sf dt (Right d) = (Right d, left $ addtime dt bc)
addtime :: DTime -> SF a b -> SF a b addtime add sf = SF sf' where sf' dt a = runSF sf (dt + add) a
but there's a pretty clear space leak here with repeated "Right" calls, and I'm not sure if the inner signal should see the lost time or not. Perhaps signal functions shouldn't be an instance of ArrowChoice at all? Any insights would be appreciated. -- ryan

On 9/29/07, Ryan Ingram
first bc = SF sf where sf dt ~(b,d) = ((c,d), sfFirst bc') where (c, bc') = runSF bc dt b
One question I had was about the implementation of "first". Is it important that the pair match be lazy? Or is it safe to make it strict? What are the advantages and disadvantages of each choice?
The pattern match has to be lazy to make ArrowLoop/loop work.
but there's a pretty clear space leak here with repeated "Right" calls, and I'm not sure if the inner signal should see the lost time or not.
In the original implementation, the inner signal function is "suspended" or "frozen in time" when the input stream is not selecting it. While your implementation wants the inner signal function to "remember and recover" the lost time when it's not selected. This would require the inner signal function to handle arbitarily large delta time by itself though. I guess either would make sense in different situations, so the decision is purely yours. Also you should be able to make the leak go away by forcing the accumulated delta time to be fully evaluated before being passed on. Regards, Paul Liu
participants (2)
-
Paul L
-
Ryan Ingram