runCommands :: Unboxed a => [(Command, Pos, Pos)] -> (Command -> a -> a) -> Int
runCommands commands language = (reduce . elems) $ runSTUArray $ do
  a <- newSTUArray ((0, 0), (999, 999)) zero
  forM_ commands $ \(command, (x1, y1), (x2, y2)) ->
    forM_ [(x, y) | x <- [x1..x2], y <- [y1..y2]] $ \pos -> do
      val <- readSTUArray a pos
      writeSTUArray a pos (language command val)
  return a
runCommands :: Unboxed a => [(Command, Pos, Pos)] -> (Command -> a -> a) -> Int
runCommands commands language = (reduce . elems) $ runSTUArray $ do
  a <- newSTUArray ((0, 0), (999, 999)) zero
  forM_ commands $ \(command, (x1, y1), (x2, y2)) ->
    forM_ [(x, y) | x <- [x1..x2], y <- [y1..y2]] $ \pos -> do
      val <- readSTUArray a pos
      writeSTUArray a pos (language command val)
  return a
runCommands commands language = (reduce . elems) $ runSTUArray $ do
  a <- newSTUArray ((0, 0), (999, 999)) zero
  forM_ commands $ \(command, (x1, y1), (x2, y2)) ->
    forM_ [(x, y) | x <- [x1..x2], y <- [y1..y2]] $ \pos -> do
      val <- readSTUArray a pos
      writeSTUArray a pos (language command val)
  return a