为什么我们将结构翻转称为“序列”,为什么要谈论“遍历”和“遍历”呢?
我将在haskell中将这些概念的实现添加为讨论的问题...
class (Functor t, Foldable t) => Traversable t where
{-# MINIMAL traverse | sequenceA #-}
-- | Map each element of a structure to an action, evaluate these actions
-- from left to right, and collect the results. For a version that ignores
-- the results see 'Data.Foldable.traverse_'.
traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
traverse f = sequenceA . fmap f
-- | Evaluate each action in the structure from left to right, and
-- and collect the results. For a version that ignores the results
-- see 'Data.Foldable.sequenceA_'.
sequenceA :: Applicative f => t (f a) -> f (t a)
sequenceA = traverse id
答案 0 :(得分:3)
这是“ 到序列”,而不是“ a”。即"Arrange in a particular order",从左到右。这是sequence :: Monad m => [m a] -> m [a]
的概括(请注意旧的base
版本),这可能会使名称更明显。
答案 1 :(得分:3)
让我们首先考虑fmap
:
fmap :: Functor t => (a -> b) -> t a -> t b
我们可以描述在a
中找到所有t a
值并将一个函数应用到它们上的作用。请注意,除了无限结构的恶作剧外,就最终结果而言,fmap
的实现到达a
值以对其进行修改的顺序并不重要。
现在让我们看一下traverse
:
traverse :: (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b)
像fmap
,traverse
一样,它还涉及将一个函数应用于结构中找到的值(难怪traverse
的先驱者被称为mapM
)。 traverse
但是也会为每个a
值(f
中的a -> f b
)产生适用效果,并且涉及以某种顺序组合这些效果以获得总体f (t b)
个结果。通常(即,只要f
不是可交换的应用程序,例如Maybe
),效果的顺序就会影响结果。就是这样,任何Traversable
实例都对应于将访问结构中值的特定顺序。 “穿越”(Will Ness指出,“穿越或穿越”)是为了传达这种方向感。
在相关说明中,traverse
可以分解为一个普通映射,该映射会产生效果,然后对这些效果进行排序...
sequenceA :: (Applicative f, Traversable t) => t (f a) -> f (t a)
traverse f = sequenceA . fmap f
sequenceA = traverse id
...按“序列”名称进行操作。
还值得强调的是,traverse
确实捕获了在每个站点进行结构化和执行操作的各种方式(参见for
是flip traverse
的名称)。特别是,我们通过选择fmap
作为应用函子(即实际上没有产生任何效果)来恢复Identity
,并通过选择{{ 1}}。我们 无法使用foldMap
进行的操作包括删除,复制或重新排列元素-不允许像一般的折叠/变形处理那样以任意方式拆除数据结构。使用Monoid m => Const m
,我们可以遍历traverse
结构,但是不能重塑它。