## Arrows in Haskell: bumpy first steps

I was reading up on arrows, specifically A New Notation For Arrows, but ran into some trouble. Here's what I discovered.

Firstly, I started out with:

newtype SF b c = SF { runSF :: [b] -> [c] }

That is, I wanted to process lists. I implemented the Arrow instance as found in the above paper without too much difficulty:

instance Arrow SF where arr f = SF (map f) SF f >>> SF g = SF (g . f) first (SF f) = SF (uncurry zip . (f *** id) . unzip) second (SF f) = SF (uncurry zip . (id *** f) . unzip)

But then the trouble arrived - I suddenly noticed that the paper was
using **infinite** sequences, not the finite sequences I was
using myself. Trying to implement an ArrowLoop as per the paper led to
horrible grief:

-- instance ArrowLoop SF where -- loop (SF f) = SF (loop (unzip . f . uncurry zip))

The problem is that this is far too strict - on non-empty input it caused stack overflow crashes, which isn't exactly what I wanted. I found the solution in Programming With Arrows (page 17), which involves some subtlety with lazy patterns:

instance ArrowLoop SF where loop (SF f) = SF $ \as -> let (bs,cs) = unzip (f (zip as (stream cs))) in bs where stream ~(x:xs) = x:stream xs

Then a length-preserving delay function for ArrowCircuit (not sure yet why this might be necessary or otherwise desireable, but it seems sensible) completes the base code to build funky circuits with:

class ArrowLoop a => ArrowCircuit a where delay :: b -> a b b instance ArrowCircuit SF where delay x = SF (init . (x:))

The counter is implemented exactly as in the Notation paper, and now it works!

counter :: ArrowCircuit a => a Bool Int counter = proc reset -> do rec next <- delay 0 -< out + 1 out <- returnA -< if reset then 0 else next returnA -< out

And if you need proof:

main :: IO () main = do let x = runSF counter print (x (map b "tfftfffftfftffttfttfff")) where b 't' = True b 'f' = False -- outputs [0,1,2,0,1,2,3,4,0,1,2,0,1,2,0,0,1,0,0,1,2,3]

Should be fun to play around with this some more, now I've got the big headaches out of the way (I hope).