我有一个输出值列表(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 (:)))
Arrow
并不能完成这个任务。你可能需要使用ArrowApply
或者一些特定于你所使用的箭头类型的 lifting 函数。 - hammar