-- !! Make sure that state threads don't escape -- !! (example from Neil Ashton at York) -- module ShouldFail where import GHC.Arr import Control.Monad.ST ( runST ) type IndTree s t = STArray s (Int,Int) t itgen :: Constructed a => (Int,Int) -> a -> IndTree s a itgen n x = runST ( newSTArray ((1,1),n) x) itiap :: Constructed a => (Int,Int) -> (a->a) -> IndTree s a -> IndTree s a itiap i f arr = runST ( readSTArray arr i >>= \val -> writeSTArray arr i (f val) >> return arr) itrap :: Constructed a => ((Int,Int),(Int,Int)) -> (a->a) -> IndTree s a -> IndTree s a itrap ((i,k),(j,l)) f arr = runST (itrap' i k) where itrap' i k = if k > l then return arr else (itrapsnd i k >> itrap' i (k+1)) itrapsnd i k = if i > j then return arr else (readSTArray arr (i,k) >>= \val -> writeSTArray arr (i,k) (f val) >> itrapsnd (i+1) k) itrapstate :: Constructed b => ((Int,Int),(Int,Int)) -> (a->b->(a,b)) -> ((Int,Int)->c->a) -> (a->c) -> c -> IndTree s b -> (c, IndTree s b) itrapstate ((i,k),(j,l)) f c d s arr = runST(itrapstate' i k s) where itrapstate' i k s = if k > l then return (s,arr) else (itrapstatesnd i k s >>= \(s,arr) -> itrapstate' i (k+1) s) itrapstatesnd i k s = if i > j then return (s,arr) else (readSTArray arr (i,k) >>= \val -> let (newstate, newval) = f (c (i,k) s) val in writeSTArray arr (i,k) newval >> itrapstatesnd (i+1) k (d newstate)) -- stuff from Auxiliary: copied here (partain) sap :: (a->b) -> (c,a) -> (c,b) sap f (x,y) = (x, f y) fap :: (a->b) -> (a,c) -> (b,c) fap f (x,y) = (f x, y) nonempty :: [a] -> Bool nonempty [] = False nonempty (_:_) = True -- const :: a -> b -> a -- const k x = k -- id :: a -> a -- id x = x compose :: [a->a] -> a -> a compose = foldr (.) id class Constructed a where normal :: a -> Bool instance Constructed Bool where normal True = True normal False = True instance Constructed Int where normal 0 = True normal n = True instance (Constructed a, Constructed b) => Constructed (a,b) where normal (x,y) = normal x && normal y -- pair :: (Constructed a, Constructed b) => a -> b -> (a,b) -- pair x y | normal x && normal y = (x,y) instance Constructed (Maybe a) where normal Nothing = True normal (Just _) = True just :: Constructed a => a -> Maybe a just x | normal x = Just x