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
並列対称配列計算が必要な状況のように、より強力な配列ライブラリを使用する必要があります。