【问题标题】:Map which must contain all possible keys?必须包含所有可能键的映射?
【发布时间】:2015-05-15 03:13:50
【问题描述】:

Haskell 有多种数据结构,如Map key value,在内部使用树或哈希映射。使用这种数据结构时,有可能在进行查找时,键不存在。

在我的用例中,可能的键集是有限的(从技术上讲,它们在 EnumOrd 中),我只对包含所有键的映射感兴趣。

如何创建一个类似map的数据结构,保证所有键都存在于map中,即它可以有一个非部分函数lookup :: Map key value -> key -> value(可能对key类型、Ord或@987654327有约束@ 或其他)?已经有这样的东西了吗?

换句话说:我想要一个只有在插入所有可能的键时才能查询的数据结构。我可以使用常规的MapfromMaybe,但我不想指定默认值——我想在类型级别保证永远不需要默认值。

【问题讨论】:

  • 地图应该为您没有手动插入的键返回什么值?如果每个键都相同,则可以改用 Data.Maybe 中的 fromMaybe
  • 你不是说lookup :: Ord key => Map key value -> key -> value吗?你确实需要Ord 约束...
  • @ThreeFx 我用更多细节更新了这个问题。
  • 在我看来你想要的只是一个总的k -> v 函数。
  • 有什么理由不使用数组?

标签: haskell data-structures types


【解决方案1】:

您应该研究一种称为 memo(ization) 尝试的技术。函数类型A -> B 的备忘录树是一种数据类型,它将该类型的函数表示为记录所有参数/结果组合的数据结构。您可能会浏览一些链接:

但长话短说,Haskell 中的 memo 尝试作为延迟构建的潜在无限搜索树出现,其中每个键的值是通过应用我们正在记忆的函数来计算的。

备忘录尝试可能并不完全符合您的要求,但该技术很有可能适用于您的目标。

【讨论】:

    【解决方案2】:

    您正在寻找的结构只是一个函数:Key -> Value。 您可以插入(或实际上替换)以下值

    insert :: (Key -> Value) -> Key -> Value -> (Key -> Value)
    insert f k v k' = if k == k' then v else f k'
    

    keysvalues 函数实现起来很简单(您只需要将 Key 类型设为 Enum)。 编译器可以警告您函数是否为部分函数(最终,无论您使用哪种数据结构,您都无法阻止某人插入 undefined 值)。

    【讨论】:

    • 请注意,在同一键 k 更新 n 次后,更新后的函数将产生 O(n) 惩罚以访问每个其他键的值。不幸的是,a->b 并不是一个理想的“数据结构”更新所涉及的。
    • 我同意这一点。它不是真正的数据结构,并且对更新的响应非常好。但是,使用函数作为参数而不是特定的数据结构是好的,因为用户可以根据需要使用任何数据结构。
    猜你喜欢
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2020-09-05
    • 1970-01-01
    • 1970-01-01
    • 2015-12-30
    相关资源
    最近更新 更多