I have an arrow which outputs a list of values (a b [c]
) and another arrow which accepts a single value of that type (a c d
). What I need basically is a way to chain them or uplift the second arrow to a [c] [d]
.
You cannot do this with just Arrow
type class. Lifting a b c
into a [b] [c]
requires choice between []
and (:)
case. Luckily for us, ArrowChoice
offers exactly this operation.
mapA :: ArrowChoice a => a b c -> a [b] [c]
mapA f = proc list -> case list of
[] -> returnA -< []
x:xs -> do
y <- f -< x
ys <- mapA f -< xs
returnA -< y:ys
Your function is then simply:
chain :: ArrowChoice a => a b [c] -> a c d -> a b [d]
chain f g = f >>> mapA g
Without proc
notation, we would need a function that translates list constructors into Either
:
listCase :: [a] -> Either () (a, [a])
listCase [] = Left ()
listCase (x:xs) = Right (x,xs)
mapA f = arr listCase >>>
arr (const []) ||| (f *** mapA f >>> arr (uncurry (:)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With