
I'm trying to do Exercise 2.5.2 from John Hughes's "Programming with Arrows". It asks to make the type SP defined as (notation is slightly different)
data SP a b = Inp (a -> SP a b) | Out b (SP a b)
an instance of Arrow, ArrowChoice and ArrowLoop. Some parts of it are straightforward, e.g.
arr f = fix $ \sp -> Inp $ \x -> Out (f x) sp
Some are a bit tricky; for "first" I ended up with code
first = fix first' where first' f sp = Inp $ \(x,z) -> let g = firstL x h = firstR z in case sp of Inp _ -> (g . h) f sp Out _ _ -> (h . g) f sp firstL x f (Inp fsp) = f $ fsp x firstL x f sp = first' (firstL x f) sp firstR z f (Out y sp) = Out (y,z) $ f sp firstR z f sp = first' (firstR z f) sp
which is a bit funny. But the real problem I don't know how to deal with is "loop". My first attempt was somethig like this:
loop (Out (y,z) sp) = Out y $ loop' z loop sp where loop' z f (Inp fsp) = Inp $ \x -> f $ fsp (x,z) loop' z f (Out (y,z') sp) = Out y $ loop' z' (loop' z f) sp
since I thought it's pointless to make a loop that don't do any output. But then I ran into trouble: *StreamProc> process (loop returnA) [1..10] *** Exception: g:/StreamProc.hs:(26,4)-(28,90): Non-exhaustive patterns in function loop So I realized that both arr and first are doing input first and output second, and that causes this error. I've tried to fix this with
loop (Inp fsp) = Inp $ \x -> let Out (y,z) sp = fsp (x,z) in Out y $ loop sp
This works as desired: *StreamProc> process (loop returnA) [1..10] [1,2,3,4,5,6,7,8,9,10] But it seems to solve the problem by shifting it one step away from us. I'm not sure this is enough. Any advice/suggestions?