Data.Vector的unsafeFreeze/unsafeThaw有多"不安全"?

cem*_*ick 4 haskell st-monad

在对文件Data.Vector.unsafeFreeze说:

不安全[ly]将可变向量转换为不可变向量而不进行复制.在此操作之后可能不使用可变载体.

我想详细描述这里"不安全"的含义.在实验上,它似乎"仅"意味着对原始可变载体的进一步修改将导致返回的不可变向量unsafeFreeze不再是纯的:

$ import qualified Data.Vector as V
$ import qualified Data.Vector.Mutable as MV
$ import Control.Monad.ST
$ :{
$ |runST $ do
$ |        mv <- V.thaw $ V.fromList [0..10]
$ |        v <- V.unsafeFreeze mv
$ |        MV.write mv 0 (-1)
$ |        MV.write mv 1 (-2)
$ |        v' <- V.freeze mv
$ |        v'' <- V.unsafeFreeze mv
$ |        return (v, v', v'')
$ |:}
([-1,-2,2,3,4,5,6,7,8,9,10],[-1,-2,2,3,4,5,6,7,8,9,10],[-1,-2,2,3,4,5,6,7,8,9,10])
Run Code Online (Sandbox Code Playgroud)

我可以想象一个修改"不安全"冻结中使用的来源做各种粗糙的事情会导致更糟糕的行为,例如segfaulting.不幸的是,我很快就忘记了尝试阅读不安全操作的来源.

我可以依靠所说的杂质是这些操作"不安全"的唯一方式吗?

对于上下文:我需要在一个通常不可变的数据结构上实现各种修改算法,而不是在内部可变性范围内重用其面向公众的API会非常不方便(因为AFAICT没有办法一般地访问两个可变的和不可变的向量).(Ab)使用unsafeFreeze当我需要使用该API时,它将是完美的逃生舱,只要我不会在路上设置更多令人不快的副作用.

And*_*ács 8

此使用模式可能会崩溃:请参阅此消息以供参考.原因是改变不可变数组会产生较小的GC根,而实际上对次要GC不可见.仅当您的阵列位于旧的GC生成且写入的对象位于新一代中时才会出现此错误,因此您不会使用最简单的测试触发它.