我对 Haskell 还很陌生,所以非常感谢您的帮助!
我正在使用 IOArray 来更新恒定空间中的随机元素。我有一个如下所示的包装:
data W = W{ arr::IO (IOArray Int Node), n::Int, ... }
但是,我找不到更新 arr
的方法,以便在传递包装器时它是可见的,而不需要执行 wrappper{arr = x}
之类的操作,这会浪费大量GC时间。在测试中,结果证明它太慢了。
有没有办法更新arr
,使其全局可见?谢谢!
最佳答案
这是如何使用 ST 数组的快速示例
import Data.Array.ST hiding (unsafeThaw) -- Deprecated
import Data.Array (Array)
import Data.Array.Unsafe (unsafeThaw) -- If you really really really need it
newtype W a = W {arr :: Array Integer a}
modifyW :: a -> W a -> W a
modifyW v (W arr) = W $ runSTArray $ do -- The double $ is on purpose, . doesn't
-- play so well with Rank n types.
a <- thaw arr -- Turn `arr` into something we can modify
writeArray a 1 v -- modify it
return a
这将确保计算是纯粹的,但数组不会在modifyW
内复制,所有这些修改都是恒定时间。如果您根本无力承担任何复制费用,您可以使用unsafeThaw
。但这很好..不安全。它实际上会修改纯数组,因此您必须非常小心,不要在运行 modifyW
后尝试使用纯结构。由于惰性评估,这比听起来要困难得多,因此我警告您不要这样做。
使用这种风格,您可以从纯Array
中读取,然后当您需要修改它时,您可以在ST
monad中运行,这让您可以做不纯粹的事情,但是不会让它们渗透到程序的其余部分。
关于arrays - Haskell 可变结构与不可变 Shell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19981685/