将类型 `a b [c]` 和 `a c d` 的箭头链接起来。

6

我有一个输出值列表(a b [c])的箭头和另一个接受单个该类型值(a c d)的箭头。基本上我需要的是一种将它们链接起来或将第二个箭头提升到a [c] [d]的方法。


3
我认为仅仅使用 Arrow 并不能完成这个任务。你可能需要使用 ArrowApply 或者一些特定于你所使用的箭头类型的 lifting 函数。 - hammar
1个回答

5
您不能仅使用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 (:)))

非常好!谢谢。我会开始测试它。 - Nikita Volkov
刚在John Hughes的《箭头编程》(Programming with Arrows)一书中找到了这个解决方案。[链接](http://www.cs.chalmers.se/~rjmh/afp-arrows.pdf) - Nikita Volkov
@NikitaVolkov:啊,是的,我记得读过那篇论文。那就是我大部分箭头知识的来源。 - Vitus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接