I read John Hughes Programming with arrows, and I got the first exercise in which he asks the reader to implement the general filter function for arrows, filterA. The spectrum says that it should behave like a filter over (->) arrows and filterM over Kliesli keys. I tried to implement it as follows, but what I ended up looking a little easier than other examples that I saw in the online solution. I'm afraid that something was missing, but my answer seems to work, as the spec shows. It matches the filter for → and filterM for the Kliesli arrows. It also works in a smart way for stream functions.
listcase [] = Left () listcase (x:xs) = Right (x,xs) filterA :: forall a arr. ArrowChoice arr => arr a Bool -> arr [a] [a] filterA f = arr listcase >>> arr (const []) ||| (switchA *** filterA f >>> arr (uncurry (++))) where switchA :: ArrowChoice arr => arr a [a] switchA = (f &&& id) >>> arr (\(b,x) -> if b then [x] else [])
Is this an acceptable implementation?
source share