我正在使用来自vector库的MVector来表示图的某些邻接表。这个问题需要对vector包有很好的了解。
我希望我的一些图形函数以可变图形作为输入,因为它们可能会更改它。而其他一些函数应该将不可变的图形作为输入,因为它们不打算更改它。
到目前为止,我拥有的每个图形函数都将可变图形作为输入。这不太好。
我喜欢从这里https://hackage.haskell.org/package/vector-0.12.1.2/docs/Data-Vector-Generic.html中的unsafeFreeze如何允许在O(1)中获取矢量的不可变版本。 我相信,在底层它确实没有做任何其他事情,只是将类型转换。
基本上我希望能够以零成本“不安全地”频繁冻结任何复杂的可变结构,以便我可以将其传递给需要不可变参数的函数。就像在任何常见的编程语言中一样。尽管有“不安全”的前缀,但如果冻结结构在用作不可变参数后立即被丢弃,则我认为这不是不安全的实践。垃圾回收不应发生,因为可变版本未被丢弃,冻结版本应指向与可变版本相同的内存表示。
谢谢。
我希望我的一些图形函数以可变图形作为输入,因为它们可能会更改它。而其他一些函数应该将不可变的图形作为输入,因为它们不打算更改它。
到目前为止,我拥有的每个图形函数都将可变图形作为输入。这不太好。
我喜欢从这里https://hackage.haskell.org/package/vector-0.12.1.2/docs/Data-Vector-Generic.html中的unsafeFreeze如何允许在O(1)中获取矢量的不可变版本。 我相信,在底层它确实没有做任何其他事情,只是将类型转换。
基本上我希望能够以零成本“不安全地”频繁冻结任何复杂的可变结构,以便我可以将其传递给需要不可变参数的函数。就像在任何常见的编程语言中一样。尽管有“不安全”的前缀,但如果冻结结构在用作不可变参数后立即被丢弃,则我认为这不是不安全的实践。垃圾回收不应发生,因为可变版本未被丢弃,冻结版本应指向与可变版本相同的内存表示。
我遇到的问题是如何冻结视为可变向量的图形的问题。到目前为止,我唯一想出的方法是使用unsafeFreeze
在每个可变子向量上调用来生成主向量的新不可变版本。但这在主向量长度为n时是O(n)的。这是不可接受的。
澄清一下,仅冻结主向量是不够的,因为它会给我一个冻结的可变向量的向量。理论上应该有一种以零成本冻结所有内容的方法,因为内部内存表示根本不应更改。这应该只是一个转换。
有没有办法以(非常便宜的)O(1)的方式冻结一个可变向量的可变向量?
我知道这个问题只涉及到vector
包。如果您有可变向量的其他包建议,我很乐意听取。
请不要回答“使用不可变结构。结束。” 我的观点是,图形、不可变性和性能通常不搭配。谢谢。
unsafeFreezeArray#
是编译器原语。其中的#
并没有实际意义,它只是名称的一部分。实现在这里。它似乎有两个作用:重写“信息表”(运行时类型信息)和(隐式地)“转换”指针。一个unsafeCoerce
可能可以工作(实际上很少有东西使用运行时类型信息),但我会说你不能这样做。使用类型类解决方案来重载操作以使其适用于不可变和可变图形? - HTNWtype family Mut s (x :: k) = (r :: k) | r -> x
。这使我能够重新创建mut模式,就像其他现代语言(如Rust)中看到的那样。现在,我想让我的整个代码库变得漂亮,但老实说,我觉得这个向量包很丑。我将尝试学习如何使用不安全的强制转换。我也认为这可能是一个好主意。 - jam