你使用newArray
, 它的类型是ST s (STArray s (Int, Int) Int)
. 然而,你在main
函数体中使用它,这意味着你do
必须有一个IO
类型。ST
is not IO
,所以类型不能匹配。
您应该首先将其移动newArray
到可以访问ST
monad 的上下文中。这个上下文当然在 的正文中是可用的runSTArray
,所以将正文更改为:
runSTArray $ do
arr <- newArray ((0,0), (5,5)) 0 :: ST s (STArray s (Int, Int) Int)
par (writeArray arr (1,1) 17) (writeArray arr (2,2) 23)
return arr
然后,您需要重新考虑par
行为方式。par
用于创建并行纯计算,不能用于单子动作;monad 通常根本无法并行化。特别是,ST
monad 甚至没有为并行计算提供任何替代方案。由于对数组的并行写入可能会导致竞争条件(如果覆盖同一个单元格会发生什么?哪个写入会计数,哪个不会?),在这里允许并行是不安全的。您必须按顺序更改数组:
runSTArray $ do
arr <- newArray ((0,0), (5,5)) 0 :: ST s (STArray s (Int, Int) Int)
writeArray arr (1,1) 17
writeArray arr (2,2) 23
return arr
但是,写入并不昂贵。可能是昂贵的值的计算。假设您要计算17
并23
在运行中;然后您可以执行以下操作:
let a = someLongCalculation 12534
b = a `par` (someLongCalculation 24889)
writeArray arr (1, 1) a
writeArray arr (2, 2) b
最后,你必须意识到runSTArray
返回结果数组,所以你必须像这样存储它:
import Control.Monad
import Control.Monad.ST
import Control.Parallel
import Data.Array.ST
main =
let pureArr =
runSTArray $ do
arr <- newArray ((0,0), (5,5)) 0 :: ST s (STArray s (Int, Int) Int)
writeArray arr (1,1) 17
writeArray arr (2,2) 23
return arr
in print pureArr
我不认为STArray
s 是正确的解决方案。您应该使用功能更强大的数组库,例如repa
在需要并行对称数组计算的情况下。