【问题标题】:Haskell Immutable data structure - the Map data typeHaskell 不可变数据结构 - Map 数据类型
【发布时间】:2018-04-18 16:58:04
【问题描述】:

我对 Haskell - Map 中的这种数据类型感到困惑。特别是,有一个函数调用 insert(来自 Data.Map 模块),它允许您将新值附加到 Map 数据结构。所以,这是我的困惑。如果 haskell 数据结构是不可变的,如何将新数据插入到现有的 Map 数据结构中?

【问题讨论】:

  • 你不能,你构造一个包含新键的新地图。

标签: haskell data-structures immutability key-value


【解决方案1】:

insert 实际上并没有修改输入 Map。它返回一个 Map,其中包含与原始Map 相同的条目,以及您要插入的条目。

在底层,编译器实际上可能不必将所有旧条目复制到新的Map,不过;如果它确定没有其他东西在使用输入Map,它可以重用原始文件。不变性是语言的属性,不一定是语言的实现

【讨论】:

  • 确实,在基于平衡 BST 的实现中,insert 只需要复制树的 O(log N) 个节点,并重用大部分旧的(不可变的)树。
  • 如果编译器可以确定没有对旧值的引用,则允许编译器就地修改值,但据我所知,它们都没有确实。但并非所有内容都丢失了:Map 被实现为一棵树,未更改的子树可以(并且正在)在旧的Map 和新的Map 之间共享。无论其他东西是否使用输入 Map,这都是允许的(因为不变性保证共享不会导致混叠问题)。
【解决方案2】:

也许举个例子会更清楚。

Prelude> let map1 = empty
Prelude> map1
fromList []

Prelude> let map2 = insert "Lemon" 6 map1
Prelude> map2
fromList [("Lemon", 6)]

Prelude> map1
fromList []

Prelude> let map3 = insert "Lime" 7 map2
Prelude> map3
fromList [("Lime", 7), ("Lemon", 6)]

Prelude> map2
fromList [("Lemon", 6)]

Prelude> map1
fromList []

每次我们定义一个新变量(map1map2map3)时,之前版本的Map 保持完全不变。一旦我们定义了(例如)map1 包含键 "Lemon",就没有什么可以改变这个定义了。我们可以创建一个包含更多键(或更少键)的新映射,但我们不能更改 map1 本身。

【讨论】:

    猜你喜欢
    • 2014-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-14
    • 1970-01-01
    • 2021-05-08
    • 2018-11-29
    相关资源
    最近更新 更多