相当于Haskell的Foldable和Traversable只是Clojure中的一个序列吗?

时间:2014-08-22 08:16:39

标签: haskell clojure sequence traversable foldable

在Haskell中,我们看到Foldable and Traversable landing in Haskell prelude

这些都在sequences上进行操作。

Prelude Data.Sequence> map (\n -> replicate n 'a') [1,3,5]
["a","aaa","aaaaa"]
Prelude Data.Sequence> fmap (\n -> replicate n 'a') (1 <| 3 <| 5 <| empty)
fromList ["a","aaa","aaaaa"]

我的问题是相当于Haskell的Foldable和Traversable只是一个sequence in Clojure

假设:

2 个答案:

答案 0 :(得分:16)

否。虽然任何代表有限元素序列的Functor都是Traversable(因此Foldable),但还有很多其他结构Traversable,但不是序列式的,因为他们没有明显的连接概念。将有一种方法来获得包含元素的序列,但结构可能不仅仅包含该序列。

Traversable f实际上是什么意思是f x类型的结构包含有限数量的x类型的元素,并且有一些方法traverse结构正好访问x的每个元素一次。所以像#34;语法中的术语,被视为包含变量&#34;可以是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对所有元素执行操作。我们通过将fmappure = id作为普通申请来获得<*>

instance Functor Term where
  fmap = fmapDefault

,其中

fmap :: (x -> y) -> Term x -> Term y

实现同时重命名

同时,Foldable实例

instance Foldable Term where
  foldMap = foldMapDefault

使pure将一些monoid和<*>的中性元素赋予组合操作,因此我们得到类似reduce的操作。如,

foldMap (:[]) :: Term x -> [x]

给出了术语中出现的变量列表。也就是说,我们总是可以从Traversable数据中获取元素序列,但数据可能具有除这些元素之外的结构。 Term具有变量以外的结构(ValAdd s),并且不太明确&#34; cons&#34;语法树的意思。

因此,虽然比序列更多的结构是Traversable,但Traversable接口为您提供的序列操作更少。 Traversable的要点是概括 map -like和 reduce -like操作,而不是捕获 list -ness。

答案 1 :(得分:1)

我想在Foldable and Traversable上指出Haskell wiki文档。

首先,可折叠可遍历是两种不同的类型。对于可折叠,维基页面发表的评论似乎暗示它与Clojure序列几乎相同。每个可折叠都有一个代表作为列表:

toList :: Foldable a => [a]
toList a = foldr (:) [] a

和(纠正我,如果我错了)似乎折叠结构与折叠相关列表相同,即:

foldr f b a = foldr f b (toList a)

在这个等式中,左边的foldr是通用版本,而右边的那个是列表上的那个。

Haskell和Clojure之间的主要区别在于Clojure要求您自己应用toList函数,以便在折叠/减少数据结构之前将数据结构转换为序列。对于平面数据结构(即列表,向量,哈希映射......)toList只是标识函数,因此您看不到它。另一方面,对于像树这样的东西,你需要在折叠它之前调用像tree-seq这样的函数。