我有一个箭头,它输出值列表(a b [c]
),另一个箭头则接受该类型的单个值(a c d
)。我基本上需要的是将它们链接起来或将第二个箭头提升到a [c] [d]
的方法。
最佳答案
您不能仅使用Arrow
类型类来执行此操作。将a b c
提升为a [b] [c]
时需要在[]
和(:)
大小写之间进行选择。对我们来说幸运的是,ArrowChoice
恰好提供了此操作。
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
然后,您的功能就是:
chain :: ArrowChoice a => a b [c] -> a c d -> a b [d]
chain f g = f >>> mapA g
没有
proc
表示法,我们需要一个将列表构造函数转换为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 (:)))