2

我对 Haskell 还很陌生,因此感谢您的帮助!

我正在使用 IOArray 来更新恒定空间中的随机元素。我有一个看起来像这样的包装器:

data W = W{ arr:: IO (IOArray Int Node), n :: Int, ... }

但是,我找不到更新的方法,arr以便在传递包装器时不做类似的事情就可以看到它wrappper{arr = x},这会浪费大量的 GC 时间。在测试中,它变得太慢了。

有什么方法可以更新arr以使其在全球范围内可见吗?谢谢!

4

1 回答 1

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运行后尝试使用纯结构。由于惰性评估,这比听起来要困难得多,所以我会提醒你不要这样做。

使用这种风格,你从 pure 中读取Array,然后当你需要修改它时,你在STmonad 中运行,这让你做不纯的事情,但不会让它们渗入你的程序的其余部分。

于 2013-11-14T16:17:35.037 回答