如何为 Arrows 写下顺序?
How could sequence be written down for Arrows?
sequenceA
是一个众所周知的函数:
sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
我想知道我们是否可以为箭写下类似的东西。不幸的是,我没有设法实现以下内容:
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
层呢?我应该注意到,在 this question, duplode 下的评论中指出:
...between (.)
, id
, arr
and first
, there isn't anything that allows collapsing two a r
layers into one.
如果他们是对的,我们需要 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 ()
层?
所以,我的问题是:
sequenceArr :: (Traversable t, Arrow a) => t (a b c) -> a b (t c)
- 我们可以写下来吗?如果是,怎么做?
- 有什么方法可以去除
a b
层 (Arrow a
)。如果是这样,为什么当我们写下 join
for Arrow
时它们不起作用(如果它们实际上不起作用)?
- 我们需要
ArrowApply
吗?如果是这样,如何?能否调整我的变体以获得此结果:sequenceArr :: (Traversable t, ArrowApply a) => t (a b c) -> a b (t c)
?
As far as I understand, Applicative
generalizes Arrow
, thus, we should be able to write this down.
请记住,这里的“泛化”实际上意味着“如果我们确定 Arrow
的输入类型参数,生成的 * -> *
类型构造函数将是 Applicative
” ,您最初提出的 sequenceArr
相当于 sequenceA
专门用于可以以这种方式从箭头中挤出的应用程序。由于这些应用程序可以通过 the WrappedArrow
newtype 表示,因此一种可能的定义是:
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
.
一致
(注意这个 sequenceArr
确实与 traverse'
from Data.Profunctors.Traversing
that dfeuer 非常不同。traverse'
不是 sequenceA
的特化,而是对 traverse
的概括,所以可以说,一个完全不同的维度。)
sequenceA
是一个众所周知的函数:
sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
我想知道我们是否可以为箭写下类似的东西。不幸的是,我没有设法实现以下内容:
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
层呢?我应该注意到,在 this question, duplode 下的评论中指出:
...between
(.)
,id
,arr
andfirst
, there isn't anything that allows collapsing twoa r
layers into one.
如果他们是对的,我们需要 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 ()
层?
所以,我的问题是:
sequenceArr :: (Traversable t, Arrow a) => t (a b c) -> a b (t c)
- 我们可以写下来吗?如果是,怎么做?- 有什么方法可以去除
a b
层 (Arrow a
)。如果是这样,为什么当我们写下join
forArrow
时它们不起作用(如果它们实际上不起作用)? - 我们需要
ArrowApply
吗?如果是这样,如何?能否调整我的变体以获得此结果:sequenceArr :: (Traversable t, ArrowApply a) => t (a b c) -> a b (t c)
?
As far as I understand,
Applicative
generalizesArrow
, thus, we should be able to write this down.
请记住,这里的“泛化”实际上意味着“如果我们确定 Arrow
的输入类型参数,生成的 * -> *
类型构造函数将是 Applicative
” ,您最初提出的 sequenceArr
相当于 sequenceA
专门用于可以以这种方式从箭头中挤出的应用程序。由于这些应用程序可以通过 the WrappedArrow
newtype 表示,因此一种可能的定义是:
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
.
(注意这个 sequenceArr
确实与 traverse'
from Data.Profunctors.Traversing
that dfeuer traverse'
不是 sequenceA
的特化,而是对 traverse
的概括,所以可以说,一个完全不同的维度。)