
-- Specs contains the options for the simulation; rollBounds simply finds the lowest and highest possible rolls -- type RollValue = Int -- type RollValueDist = Array RollValue Int probDist :: Specs -> [RollValue] -> RollValueDist probDist specs rolls = accumArray (+) 0 (rollBounds specs) [(r, 1) | r <- rolls]
It should be doing an in-place array update as it evaluates the comprehension, but apparently something's being kept in memory longer than it has an excuse for.
It does do a sequence of in-place updates, but this is another instance of the foldl space leak. The additions aren't being performed strictly, so the array is filling up with suspensions. For example: accumArray (+) 0 (1,10) [(3,1), (3,1), (3,1), ...] would produce this sequence of arrays as accumArray processed its input list: { (3,1), ... } { (3,1+1), ... } { (3,1+1+1), ... } we should really have a strict version of accumArray (the lazy version *is* useful sometimes: you can refer recursively to the final array, for example). A quick workaround in your case (GHC only, I'm afraid) is to use UArray instead, available from Data.Array.Unboxed. These arrays contain unboxed values and are therefore strict by definition; and you can use all the usual array operations including accumArray. This workaround only applies if you're using one of the types supported by UArray though (Int, Char, and other base types). Cheers, Simon
participants (1)
-
Simon Marlow