不。虽然任何类型的Functor表示元素的有限序列都将是Traversable(因此Foldable),但还有许多其他结构是Traversable,但它们不是类似序列的,因为它们没有明显的连接概念。将有一种方法可以获取包含元素的序列,但结构可能不仅仅包含该序列。
实际上,这Traversable f意味着具有 type 的结构f x包含有限多个 type 元素x,并且该结构有某种方法可以只traverse访问每个元素x一次。因此,诸如“语法中的术语,被视为包含变量”之类的东西可以是Traversable.
data Term x
= Var x
| Val Integer
| Add (Term x) (Term x)
instance Traversable Term where
traverse f (Var x) = pure Var <*> f x
traverse f (Val i) = pure (Val i)
traverse f (Add s t) = pure Add <*> traverse f s <*> traverse f t
您始终可以使用traverseto 对所有元素进行操作。我们fmap通过采取pure = id和<*>成为普通应用程序来获得。
instance Functor Term where
fmap = fmapDefault
在哪里
fmap :: (x -> y) -> Term x -> Term y
实现同时重命名。
同时,Foldable实例
instance Foldable Term where
foldMap = foldMapDefault
需要pure给一些幺半群的中性元素和<*>组合操作,所以我们得到了类似reduce的操作。例如,
foldMap (:[]) :: Term x -> [x]
给出一个术语中出现的变量列表. 也就是说,我们总是可以从Traversable数据中获取元素的序列,但数据可能具有这些元素以外的结构。Terms 具有除变量(它们Val的 s 和Adds)之外的结构,并且“cons”对于语法树的含义还不是很清楚。
因此,虽然结构比序列多Traversable,但该Traversable接口为您提供的类似序列的操作更少。的重点Traversable是概括map和reduce的操作,而不是捕获list。