2

sequenceA是一个众所周知的函数:

sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)

我想知道我们是否可以为 Arrows 写下类似的东西。不幸的是,我没有设法实现以下内容:

sequenceArr :: (Traversable t, Arrow a) => t (a b c) -> a b (t c)

据我了解,Applicative泛化Arrow,因此,我们应该能够写下来。我这样做是为了列表:

sequenceArrLst :: Arrow a => [a b c] -> a b [c]
sequenceArrLst t = let t' = (>>> arr (: [])) <$> t
                   in foldr1 (\f g -> f &&& g >>> arr (uncurry (++))) t'

然而,正如人们注意到的那样,我们并没有摆脱列表中a b图层,而是将结果包装到一个新列表中。那么,我们如何才能真正摆脱a b层呢?我应该注意到,在这个问题下的评论中,duplode指出:

...在(.)、和之间id,没有任何东西可以将两层合二为一。arrfirsta r

如果他们是对的,我们需ArrowApply要这样做吗?坦率地说,我写下来了,仍然无法摆脱里面的箭头t

sequenceArrApp :: (Functor f, ArrowApply a) => f (a b c) -> a b (f (a () c))
sequenceArrApp t = arr $ \ b -> (\ f -> arr (\ () -> (f, b)) >>> app) <$> t

可以调整这个片段以缺少a ()图层吗?

所以,我的问题是:

  1. sequenceArr :: (Traversable t, Arrow a) => t (a b c) -> a b (t c)- 我们可以写下来吗?如果是这样,怎么做?
  2. 有什么方法可以摆脱a b层(Arrow a)。如果是这样,为什么当我们写下来时它们不起作用joinArrow如果它们实际上没有)?
  3. 我们需要ArrowApply这个吗?如果是这样,怎么做?是否可以调整我的变体以获得此结果:sequenceArr :: (Traversable t, ArrowApply a) => t (a b c) -> a b (t c)
4

1 回答 1

2

据我了解,Applicative泛化Arrow,因此,我们应该能够写下来。

请记住,这里的“泛化”实际上意味着“如果我们确定 an 的输入类型参数Arrow,则生成的* -> *类型构造函数将是一个Applicative”,sequenceArr您首先提出的建议相当于sequenceA可以从箭头中挤压出来的应用程序离开。由于这些应用程序可以通过newtype表达WrappedArrow一种可能的定义是:

sequenceArr :: (Traversable t, Arrow a) => t (a b c) -> a b (t c)
sequenceArr = unwrapArrow . sequenceA . fmap WrapArrow

看看如何WrappedArrow实例化Applicative...

instance Arrow a => Applicative (WrappedArrow a b) where
    pure x = WrapArrow (arr (const x))
    liftA2 f (WrapArrow u) (WrapArrow v) =
      WrapArrow (u &&& v >>> arr (uncurry f))

... 应确认此实现在精神上与您的写作尝试一致sequenceArrLst

(请注意,这确实与dfeuer在评论中讨论的sequenceArr非常不同。与其说是 的专业化,不如说是概括了一个完全不同的维度。)traverse'Data.Profunctors.TraversingsequenceAtraverse'traverse

于 2020-07-07T05:51:39.277 回答