newArrayタイプが。のを使用しますST s (STArray s (Int, Int) Int)。ただし、main関数の本体で使用します。つまり、すべてdoの型が必要IOです。STではないIOため、タイプを一致させることはできません。
まず、モナドnewArrayにアクセスできるコンテキストに移動する必要があります。STこのコンテキストはもちろんの本文で利用できる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並列の純粋な計算を作成するためのものであり、モナディックアクションには使用できません。モナドは一般的に並列化することはできません。特に、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てその場で実行したいとします。その後、次のことを行うことができます。
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並列対称配列計算が必要な状況のように、より強力な配列ライブラリを使用する必要があります。