【问题标题】:Overlay data structure?覆盖数据结构?
【发布时间】:2011-06-12 17:29:01
【问题描述】:

我有一个嵌套的、相互递归的data structure,并希望将计算昂贵的值与某些节点相关联。实际上,我想暂时将 Pandoc 文档中的块链接到该块中出现的单词列表。

我想避免的没有吸引力的选择:

  • 扩展 Block 数据类型,使其包含单词列表,这归结为创建具有大量(脆弱)样板代码的新扩展 Pandoc 数据类型

  • 将块映射到单词列表;这是次优的,因为块太复杂而无法有效地用作键

我寻求解决方案的方向是某种覆盖数据结构,包括扩展块,但底层数据类型不受影响,因此我仍然可以使用广泛的 Pandoc 库。但也许这不是 Haskell 的思维方式……

2011-06-12 发布脚本

正如 cmets 所示,我可能高估了 Map 方法的成本,部分原因是错误的假设。确实:“没有什么比显而易见的事实更具欺骗性了”。

无论如何,我接受 hammar 的回答,因为它说明了如何创建可扩展的数据类型。

谢谢

【问题讨论】:

  • 你可以使用Map 来存储节点之间的关联吗?
  • @Don Stewart:您是指从 Block 到 WordList 的 Data.Map 吗?是的,但我担心的是,作为键的 Block 数据结构过于复杂。通常它代表整个段落及其格式,可能包括其他块。
  • 在存储为密钥之前对块进行哈希处理?
  • 或者只使用 HashMap(来自无序容器)。
  • 在放弃将 Block 作为 key 的想法之前,也许您应该尝试一下。

标签: data-structures haskell pandoc


【解决方案1】:

当现有数据类型的设计不是可扩展时,您无法向其添加内容,因此您将不得不依赖某些外部结构(例如 Map)将单词列表与每个块相关联.

但是,如果您可以更改数据类型,则可以通过概括数据类型中的递归来使其可扩展。假设您有一个这样的递归数据类型:

data Tree = Leaf | Fork String Tree Tree

我们可以为Tree的递归使用添加一个参数:

data GenTree t = Leaf | Fork String t t

现在,为了得到一棵像原始树一样的普通树,我们采用这种类型的不动点:

data Fix a = Fix (a (Fix a))
type Tree = Fix GenTree

现在,您可以在每个递归站点使用附加数据扩展该类型。以下是为标记树创建类型的方法:

data Labelled t = Labelled Int (GenTree t)
type LabelledTree = Fix Labelled

strLength :: GenTree t -> Int
strLength Leaf = 0
strLength (Fork str _ _) = length str

label :: Tree -> LabelledTree
label (Fix tree) = Fix $ Labelled (strLength tree) (fmap label tree)

instance Functor GenTree where
    fmap f Leaf = Leaf
    fmap f (Fork s l r) = Fork s (f l) (f r)

【讨论】:

  • 我理解这个答案的一半;已经为高级类型巫术 +1... 我可以看到类型 Tree = Fix GenTree = Fix (GenTree (Fix GenTree)) = Fix (Leaf | Fork Str (Fix GenTree) (Fix GenTree)) = Fix (Leaf | Fork Str Tree Tree) = Fix Tree,因此 Gentree 必须等于 Tree。这像是在类型层面上打结吗?
  • @sleepyMonad。正确,这类似于使用fix 使函数递归。例如,使用带有参数的非递归阶乘函数代替递归:fac f n = if n == 0 then 1 else n * f (n-1)。现在,使用fix 使其递归:fix fac 10
  • @sleepyMonad:可以使用扩展名FlexibleContextsUndecidableInstances 来完成。例如,对于Showderiving instance (Show (a (Fix a))) => Show (Fix a)。 (这也使用StandaloneDeriving 让编译器为我生成它。)
猜你喜欢
  • 1970-01-01
  • 2021-09-08
  • 2017-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多