我对Haskell很新,所以对任何帮助表示赞赏!
我正在使用IOArray来更新恒定空间中的随机元素。我有一个看起来像这样的包装器:
data W = W{ arr:: IO (IOArray Int Node), n :: Int, ... }
但是,我找不到更新arr
的方法,以便在传递包装器而不执行wrappper{arr = x}
之类的操作时可以看到它,这会浪费大量的GC时间。在测试中,结果太慢了。
有没有办法更新arr
以便全局可见?谢谢!
答案 0 :(得分:3)
以下是如何使用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中运行,这样你就可以做出不纯净的东西,但不会让它们流血进入你的其他计划。