I’m trying to do computation in parallel, and write the results to an STArray. I think this code shows what I’m trying to do. However, I’m getting compile errors.
import Control.Monad
import Control.Monad.ST
import Control.Parallel
import Data.Array.ST
main = do
arr <- newArray ((0,0), (5,5)) 0 :: ST s (STArray s (Int, Int) Int)
runSTArray $ do
par (writeArray arr (1,1) 17) (writeArray arr (2,2) 23)
return arr
print arr
How should I do this?
You use
newArray, which has the typeST s (STArray s (Int, Int) Int). However, you use it in the body of themainfunction, which means that everything youdomust have anIOtype.STis notIO, so the types cannot match.You should first move the
newArrayinto a context where you have access to theSTmonad. This context is of course available in the body ofrunSTArray, so change the body to:Then, you need to rethink how
parbehaves.paris for creating parallel pure computations, and cannot be used for monadic actions; monads cannot generally be parallelized at all. In particular, theSTmonad doesn’t even offer any alternatives for parallel computations; since parallel writes to an array can lead to race conditions (what happens if you overwrite the same cell? Which write will count, and which one won’t?), it is unsafe to allow parallelism here. You must change the array in sequence:However, the writes aren’t expensive; it’s the calculations of the values that might be expensive. Suppose that you want to calculate
17and23on the fly; you can then do the following:Finally, you must realize that
runSTArrayreturns the result array, so you must store it like this:I don’t think that
STArrays are the correct solution here. You should use a more powerful array library likerepain situations where you need parallel symmetrical array computations.