【发布时间】:2017-01-07 10:00:52
【问题描述】:
我正在寻找一个无 monad 的常量访问查询 O(1) 关联数组。
考虑假设的类型:
data HT k v = ???
我想构造一个不可变结构一次:
fromList :: Foldable t, Hashable k => t (k,v) -> HT k v
我想随后用恒定时间访问重复查询它::
lookup :: Hashable k => HT k v -> k -> Maybe v
似乎有两个候选库不足:
unordered-containers
unordered-containers 包含HashMap 类型的严格变体和惰性变体。 HashMaps 都有 O(log n) 查询,如 lookup 函数所记录。这个查询访问时间似乎是由于HashMap 类型的构造,它具有允许O(log n) insert 功能的内部树结构。对于许多用例来说,这是一种可以理解的设计权衡,但由于我不需要可变的HashMap,这种权衡阻碍了我的用例。
hashtables
hashtables 包含一个HashTable 类型类和三个具有不同表构造策略的实例类型。这个库的类型类定义了一个常数时间 O(1) lookup 函数定义,但它永远嵌入在 ST monad 中。没有办法“冻结”有状态的 HashTable 实现并拥有一个未嵌入有状态 monad 的 lookup 函数。当整个计算包装在一个状态单子中时,库的类型类接口设计得很好,但是这种设计不适合我的用例。
是否存在其他一些定义类型和函数的库,这些库可以构造不可变的常量访问查询O(1) 关联数组,该数组未嵌入有状态的 monad?
是否存在某种方法来包装或修改这些现有的基于散列的库以生成不嵌入在有状态 monad 中的不可变常量访问查询 O(1) 关联数组?
【问题讨论】:
-
首先:我相信你是对的。没有纯 + O(1) 查找键值结构。 OTOH,出现的第一个问题是必要的。避免使用 monad(包括避免使用 IO)是一种通常缺乏技术依据的美学选择——在这种情况下,避免使用显然要付出代价。同样,已经提出过早优化的怀疑。如果您愿意,请考虑为
hashtables库添加一个补丁,该补丁添加了冻结操作和纯查找。或者试试 HashMap 看看具体性能如何。 -
@ThomasM.DuBuisson 我在 O(1) 查询中使用了
(i,j)键矩阵,但是矩阵的维度增长得很快,而且矩阵稀疏填充上三角矩阵。内存要求不可扩展。当我找不到合适的哈希表结构来替换查找矩阵时,我感到非常震惊。有一个 feature request 用于冻结HashTable,但没有得到答复,我目前无法构建拉取请求。
标签: haskell hashmap hashtable asymptotic-complexity hackage