简短的回答是:有一些系统可以满足您的需求。例如,您可以使用ST
Haskell 中的 monad 来实现(如评论中所引用)。
ST
monad 方法来自 Haskell的Control.Monad.ST
. 用 monad编写的代码可以在方便的地方ST
使用引用 ( )。STRef
好的部分是您甚至可以ST
在纯代码中使用 monad 的结果,因为它本质上是自包含的(这基本上是您在问题中想要的)。
这种自包含属性的证明是通过类型系统完成的。ST
monad 带有一个状态线程参数,通常用 type-variable表示s
。当您进行这样的计算时,您将获得单子结果,其类型如下:
foo :: ST s Int
要真正把它变成一个纯粹的结果,你必须使用
runST :: (forall s . ST s a) -> a
你可以像这样阅读这种类型:给我一个s
类型参数无关紧要的计算,我可以给你返回计算的结果,没有ST
包袱。这基本上可以防止可变ST
变量转义,因为它们会随身携带s
,这将被类型系统捕获。
这可以用于对使用底层可变结构(如vector 包)实现的纯结构产生良好的效果。人们可以在有限的时间内摆脱不变性来做一些改变底层数组的事情。例如,可以将不可变Vector
与不纯算法包结合起来,以保持原地排序算法的大部分性能特征并仍然获得纯度。
在这种情况下,它看起来像:
pureSort :: Ord a => Vector a -> Vector a
pureSort vector = runST $ do
mutableVector <- thaw vector
sort mutableVector
freeze mutableVector
和函数是线性时间复制thaw
,freeze
但这不会破坏整体 O(n lg n) 运行时间。您甚至可以使用它unsafeFreeze
来避免另一个线性遍历,因为不再使用可变向量。