【问题标题】:Can trees be generalized to allow any traversable sub-tree?可以概括树以允许任何可遍历的子树吗?
【发布时间】:2021-04-22 10:02:27
【问题描述】:

Data.Tree 使用列表来表示以特定节点为根的子树。是否可以有两种树类型,例如一种使用列表,另一种使用向量?我希望能够编写不关心子树如何具体表示的函数,只关心子树是可遍历的,以及利用特定子树类型的函数,例如快速索引向量。

似乎类型族将是这项工作的正确工具,尽管我以前从未使用过它们,而且我不知道如何实际定义正确的族。

如果重要的话,我没有使用容器库树实例,而是使用类型

data Tree a b = Node a b [Tree a b] deriving (Show, Foldable, Generic)

data MassivTree a b = V a b (Array B Ix1 (MassivTree a b))

后者使用来自massiv的向量。

【问题讨论】:

标签: haskell tree type-families traversable


【解决方案1】:

您可以使用类型类 - 实际上您需要的类型类可能已经存在。

考虑一下:

data Tree t a = Tree a (t (Tree t a))

参数t 是更高种类的类型,它表示as 的容器。

现在定义一组 Tree 操作,限制在 Traversable 上,如下所示:

:: (Foldable t) => Tree t a -> b

您现在可以创建和操作使用任何Foldable 的树。您需要为您想要的一组操作选择正确的类型类 - Functor 可能就足够了,或者如果您正在使用单子操作执行任何操作,您可能需要 Traversable。您可以根据功能选择类型类,具体取决于它的作用。

您现在可以像这样定义Tree 类型:

type ListTree a = Tree [] a
type MassivTree r ix a = Tree (Array r ix) a

您还可以定义特定于实例的函数,以访问全部功能:

:: ListTree a -> b
-- or
:: Tree [] a -> b

Haskell 快乐!

【讨论】:

  • 谢谢。能够以最少的重写使我当前的树类型成为 Tree t a b 的特化(只需手动使其成为 Show 的实例)。所有旧功能仍然有效。
  • 这只是Cofree
  • @xgrommx 你能扩展一下吗?
  • 这里的树是 Cofree
  • @AriFordsham 关心的原因是已经有一个库可以提供这种数据类型和一系列操作,包括折叠、展开、遍历、压缩、提取值等等。这是一堆你不必自己编写的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-25
  • 2014-03-10
相关资源
最近更新 更多