-
-
Save gyk/c1f77ae0eca7c950173e to your computer and use it in GitHub Desktop.
Haskell STUArray
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
It's a pita. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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