不。虽然任何类型的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
您始终可以使用traverse
to 对所有元素进行操作。我们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
数据中获取元素的序列,但数据可能具有这些元素以外的结构。Term
s 具有除变量(它们Val
的 s 和Add
s)之外的结构,并且“cons”对于语法树的含义还不是很清楚。
因此,虽然结构比序列多Traversable
,但该Traversable
接口为您提供的类似序列的操作更少。的重点Traversable
是概括map和reduce的操作,而不是捕获list。