我有一个箭头,它输出值列表(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 (:)))

08-05 05:19