のnewArray
を使用します。ただし、main
関数の本体で使用すると、do
のすべてがIO
タイプである必要があります。 ST
はIO
ではないため、タイプは一致しません。
最初に、newArray
をST
モナドにアクセスできるコンテキストに移動する必要があります。このコンテキストはrunSTArray
の体内で利用できるのは勿論であるので、身体への変更:次に、あなたはどのように振る舞うpar
を再考する必要が
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
は、の純粋な計算を行うためのものであり、モナドアクションには使用できません。モナドは、一般に並列化することはできません。特に、ST
のモナドは、並列計算のための代替手段を提供していません。配列への並列書き込みは競合状態に繋がる可能性があります(同じセルを上書きするとどうなりますか?どの書き込みがカウントされ、どちらがどちらにならないか)、ここでは並列性を許可するのは危険です。
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
をオンザフライで計算したいとします。
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があるとは思わない:あなたはこのようにそれを保存する必要がありますので、あなたは、runSTArray
は、結果の配列を返すことを認識しなければならない、最後に
let a = someLongCalculation 12534
b = a `par` (someLongCalculation 24889)
writeArray arr (1, 1) a
writeArray arr (2, 2) b
:あなたは、次の操作を行うことができますここには正しい解決策があります。並列対称配列計算が必要な状況では、repa
のようなより強力な配列ライブラリを使用する必要があります。
パラレルアレイの操作に[Repa](http://hackage.haskell.org/package/repa)を使うべきだと思います。 – leftaroundabout