从根本上说,为什么遍历是在应用程序上定义的?

Why are traversals defined over Applicatives, fundamentally?

我最近一直在“提炼一切以达到其基础”,我一直无法找到关于 Traversable 类型类定义方式的明确理论原因,只有“它有用”的实际原因能够遍历应用性余数,很多数据类型都可以做到这一点”和很多提示。

我知道有一个适用的“家庭”,如 https://duplode.github.io/posts/divisible-and-the-monoidal-quartet.html 所述。

我还知道虽然 Traversable 遍历是应用余数,'semigroupoids' 的 Traversable1 类型类描述了应用余数,'distributive' 的 Distributive 类型类描述了函子代数。

此外,我知道 Foldable、Foldable1 和 theoretical fold family 成员描述了可以使用幺半群、半群和相应的幺半群家族成员折叠的数据类型,例如岩浆(用于折叠为二叉树)和每个的交换版本(折叠为每个的无序版本)。

因此,由于 Traversable 是 Foldable 的子类,我假设它在本质上是幺半群的,同样我假设 Traversable1 在本质上是半群的,而 Distributive 在本质上是共幺半群的(如 [=32 中的描述中所述) =]包)。

这感觉是对的,但是 Applicative 和 Apply 从何而来?有岩浆和交换版本吗?具有非平凡类群的类别中是否存在分配族?

基本上,我的问题是“这些类型类是否存在,它们是什么?如果不存在,为什么不存在?”:

class FoldableMagma t => TraversableMagma t where
    traverseMagma :: ??? f => (a -> f b) -> (t a -> f (t b))
class FoldableCommute t => TraversableCommute t where
    traverseCommute :: ??? f => (a -> f b) -> (t a -> f (t b))
class Foldable t => ContraTraversable t where
    contraTraverse :: Divisible f => (b -> f a) -> (t a -> f (t b))
-- im really not sure on this last one
-- but it's how i'd expect an endofunctor over coalgebras to look
-- which seems potentially related to traversables?

大概不太重要的奖励问题:在尝试研究这个问题时,我遇到了 'data-functor-logistic' 包 https://hackage.haskell.org/package/data-functor-logistic

这描述了 Distributive over contravariant functors 的一个版本 - 是否有等效的 Traversable over Divisibles(或 Decidables)?

我不知道有任何库实现了这些 classes,但我会尝试阐明这些 classes 代表什么。我是一名程序员,不是类别理论家,所以对此持保留态度。

Applicative 变体

ApplyMagma

ApplyMagmaclass和Applyclass的方法完全一样,只是不需要遵循结合律

class Functor f => ApplyMagma f where
    (<.>) :: f (a -> b) -> f a -> f b

如果Apply类似于半群,ApplyMagma类似于岩浆。

ApplyCommute

ApplyCommute class 将等同于 Apply class 但具有以下交换律:

f <$> x <.> y = flip f <$> y <.> x

如果 Apply 类似于半群,ApplyCommute 类似于交换半群。

Traversable1 变体

Traversable1Magma

A Traversable1Magma 可以看作是 Traversable1,提供了有关结构的更多信息。 Foldable1 class 有一个 toNonEmpty 方法,而 Foldable1Magma class 可以有一个 toBinaryTree 方法。

class (FoldableMagma t, Traversable1 t) => Traversable1Magma t where
    traverseMagma :: ApplyMagma f => (a -> f b) -> (t a -> f (t b))

Traversable1Commute

A Traversable1Commute 可以看作是 Traversable1 而没有定义元素的顺序。如果它不需要 Ord a 约束,containers 中的 Set 可能是此 class 的一个实例。 Traversable1Commute 可能是 Traversable1.

的超class
class (FoldableCommute t, Functor t) => Traversable1Commute t where
    traverseCommute :: ApplyCommute f => (a -> f b) -> (t a -> f (t b))

请注意,这些是 Traversable1 的变体,因为 ApplyMagmaApplyCommute 都没有等同于 pure 的功能。

ContraTraversable

ContraTraversable 没有任何实例。要了解原因,请查看 contraTraverse 函数的类型。

contraTraverse :: Divisible f => (b -> f a) -> (t a -> f (t b))

我们可以将其专门用于以下方面:

contraTraverse :: Monoid b => (b -> Op b a) -> (t a -> Op b (t b))

等同于以下内容:

contraTraverse ~ Monoid b => (b -> a -> b) -> t a -> t b -> a

使用 const 和 Divisible 中的 conquer 函数,这允许我们创建任何类型的值,这是不可能的。