1

我看到我可以使用 mapArray 在可变数组上映射一个函数,但似乎没有像 mapM(和 mapM_)这样的东西。mapArray 不会让我打印它的元素,例如:

import Data.Array.Storable

arr <- newArray (1,10) 42 :: IO  -- answer to Life, Universe and Everything
x <- readLn :: IO Int
mapArray (putStrLn.show) arr -- <== this doesn't work!

结果将是:

No instances for (MArray StorableArray Int m,
                  MArray StorableArray (IO ()) m)
  arising from a use of `mapArray' at <interactive>:1:0-27
Possible fix:
  add an instance declaration for
  (MArray StorableArray Int m, MArray StorableArray (IO ()) m)
In the expression: mapArray (putStrLn . show) arr
In the definition of `it': it = mapArray (putStrLn . show) arr

Haskell 中是否有类似的东西(或者在 GHC 中,即使不是标准的 Haskell)?

此外,我发现没有用于数组的 foldr/foldl 函数(可变与否)。它们存在吗?

非常感谢!

4

3 回答 3

5

导入模块Data.Traversable。它使用已经为数组和各种事物定义的实例为您想要的定义了一个类型类。它具有序列和 mapM 的通用版本,以及一些您可能不会经常使用的更通用的功能。

只是一个简单的

import Data.Traversable as T

T.mapM doIOStuff arr

工作正常。

于 2009-10-02T10:55:37.440 回答
3

如果您要进行大量突变,也许可以使用其他数组库之一?像 uvector?

除此以外,

forM_ [1..n] \$ \i ->. unsafeWrite x i 

应该没事。

于 2009-09-29T22:48:33.317 回答
2

对于打印所有元素的示例:您可以使用“ mapM_ print . elems”。

但听起来你想创建一个新数组,其中每个值都是前一个单子动作的结果?在这种情况下:

arrayMapM :: (Monad m, Ix i) => (a -> m b) -> Array i a -> m (Array i b)
arrayMapM func src =
  liftM (listArray (bounds src)) . mapM func . elems $ src
于 2009-09-29T22:46:51.667 回答