Skip to content

Instantly share code, notes, and snippets.

@gyk
Last active November 23, 2016 09:11
Show Gist options
  • Save gyk/c1f77ae0eca7c950173e to your computer and use it in GitHub Desktop.
Save gyk/c1f77ae0eca7c950173e to your computer and use it in GitHub Desktop.
Haskell STUArray
It's a pita.
-- Modify arrays in-place using ST Monad.
import Control.Monad
import Control.Monad.ST
import System.Random
import Data.Array.ST
import Data.Array.Unboxed
import Data.Array.Unsafe
randIntArray :: (Int, Int) -> Int -> StdGen -> UArray Int Int
randIntArray range n g =
let randIntList = take n $ randomRs range g
in
listArray (0, n - 1) randIntList
accumArr :: UArray Int Int -> UArray Int Int
accumArr arr = runST $ do
-- Note that this doesn't work (the compilter will complain that
-- "No instance for (MArray (STUArray s) Int (ST s1))"):
-- (a :: STUArray s Int Int) <- unsafeThaw arr
a <- unsafeThaw arr :: ST s (STUArray s Int Int)
(lo, hi) <- getBounds a
forM_ [(lo+1)..hi] $ \i -> do
let lastIx = i - 1
lastVal <- readArray a lastIx
currVal <- readArray a i
when (currVal < lastVal) $
writeArray a i lastVal
unsafeFreeze a
-- Note that the type annotations are crucial to get the code work.
minMax :: UArray Int Int -> UArray Int Int -> (UArray Int Int, UArray Int Int)
minMax arrMin arrMax = runST $ do
aMin <- unsafeThaw arrMin :: ST s (STUArray s Int Int)
aMax <- unsafeThaw arrMax :: ST s (STUArray s Int Int)
(loMin, hiMin) <- getBounds aMin
(loMax, hiMax) <- getBounds aMax
let (lo, hi) = (max loMin loMax, min hiMin hiMax)
forM_ [lo..hi] $ \i -> do
eMin <- readArray aMin i
eMax <- readArray aMax i
writeArray aMin i (min eMin eMax)
writeArray aMax i (max eMin eMax)
liftM2 (,) (unsafeFreeze aMin) (unsafeFreeze aMax)
liftM2 (,) (unsafeFreeze aMin) (unsafeFreeze aMax)
main = do
ga <- newStdGen
let a = randIntArray (0, 100) 10 ga
gb <- newStdGen
let b = randIntArray (0, 100) 10 gb
putStrLn $ "a = " ++ show a
putStrLn $ "b = " ++ show b
print (accumArr a)
print $ minMax a b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment