问题
我想创建一个数据类型,它允许快速访问和修改其元素。是否可以在 Haskell 中创建一个结构和函数,其执行速度与简单的 C++ 实现一样快?
问题详情
我正在用 Haskell 编写一个编译器。我已经用数据类型表示AST,让我们考虑以下一个:
import Prelude hiding (id)
-- this is a sample data type, the real one has got a lot of constructors
data AST = A { id :: Int, x :: AST, y :: AST, z :: AST }
| B { id :: Int }
| C { id :: Int, x :: AST, y :: AST }
| D { id :: Int, u :: AST, v :: AST, w :: AST}
每个 AST 节点都有一个唯一的标识符。我很想在 Haskell 中实现以下功能:
- 一个函数
getById
,它将返回一个O(1)
时间复杂度为选定 id 的 AST 节点。 - 能够在结构上创建“焦点”并相互独立地修改焦点元素。所以我希望能够记住一些子树的焦点,并能够在
O(1)
时间复杂度上修改每个这样的焦点。
我在考虑Zippers,但它们有 3 个问题:
- 它们(据我所知)与简单的数据类型一起使用,比如二叉树,我们可以说,我们选择“左”或“右”分支。是否有任何简单的方法可以在上述复杂数据类型上使用它们?
- 我认为他们不允许我实现
getById
具有O(1)
时间复杂度的功能,对吗? - 我认为使用 Zippers 创建一些独立的焦点是不可能的。我所说的独立焦点是指焦点,这将允许我们修改数据类型的不同部分,而无需重新计算其他焦点(在 中
O(1)
)。
C++ 的思维方式
在 C++ 中,我们将能够创建指向 AST 节点的指针数组nodePtrs
。该函数nodeById
将在 中执行O(1)
,只需访问*(nodePtrs[id])
. 因为 C++ 结构是可变的,所以我们可以在没有任何限制的情况下修改它的元素O(1)
。