--
import ST --------------------------------------------- -- Some Monad type constructors data Id x = Id x data Exception x = Ok x | Fail data Env e x = Env (e -> x) data Mult x = Mult [x] data Store s x = St(s -> (x,s)) data Output x = OP(x,String) -- Some Instance declarations instance Monad Id where return x = Id x (>>=) (Id x) f = f x instance Monad Exception where return x = Ok x (>>=) (Ok x) f = f x (>>=) Fail f = Fail instance Monad (Env e) where return x = Env(\ e -> x) (>>=) x yf = let Env f = x h e = let x = f e Env g = yf x in g e in Env h instance Monad (Store s) where return x = St(\ s -> (x,s)) (>>=) x yf = let St f = x h s1 = let (x,s2) = f s1 St g = yf x (y,s3) = g s2 in (y,s3) in St h instance Monad Mult where return x = Mult[x] (>>=) x yf = let Mult xs = x ys = map yf xs in Mult (concat[ z | Mult z <- ys ]) instance Monad Output where return x = OP(x,"") (>>=) (OP(x,s1)) f = let OP(y,s2) = f x in OP(y,s1 ++ s2) --- A few non-standard morphisms (the interface of the ADT) type Map = [(String,Value)] getEnv :: String -> (Env Map Value) getEnv nm = Env(\ s -> find s) where find [] = error ("Name: "++nm++" not found") find ((s,n):m) = if s==nm then n else find m runInNewEnv :: String -> Int -> (Env Map Value) -> (Env Map Value) runInNewEnv s n (Env g) = Env(\ m -> g ((s,n):m)) getStore :: String -> (Store Map Value) getStore nm = St(\ s -> find s s) where find w [] = (0,w) find w ((s,n):m) = if s==nm then (n,w) else find w m putStore :: String -> Value -> (Store Map ()) putStore nm n = (St(\ s -> ((),build s))) where build [] = [(nm,n)] build ((s,v):zs) = if s==nm then (s,n):zs else (s,v):(build zs) printOutput:: String -> Output () printOutput s = OP((),s) ------------------------------------------------------------------- -- A much richer monad combining many of the elements of the above type Value = Int type Maps x = [(String,x)] data M v x = M(Maps v -> Maps v -> (Maybe x,String,Maps v)) instance Monad (M v) where return x = M(\ st env -> (Just x,[],st)) (>>=) (M f) g = M h where h st env = compare env (f st env) compare env (Nothing,op1,st1) = (Nothing,op1,st1) compare env (Just x, op1,st1) = next env op1 st1 (g x) next env op1 st1 (M f2) = compare2 op1 (f2 st1 env) compare2 op1 (Nothing,op2,st2) = (Nothing,op1++op2,st2) compare2 op1 (Just y, op2,st2) = (Just y, op1++op2,st2) --- Sub classes of Monad for generic evaluation class Monad m => Eval e v m where eval :: e -> m v class Monad m => Failure m where fails :: m a class Monad m => HasEnv m v where inNewEnv :: String -> v -> m v -> m v getfromEnv :: String -> m v class Monad m => HasStore m v where getfromStore :: String -> m v putinStore :: String -> v -> m v class (Monad m,Show v) => Prints m v where write :: String -> v -> m v --------------------------------------------------------------- -- Instance declarations for the rich monad instance Failure (M v) where fails = M(\ st env -> (Nothing,[],st)) get name ((a,b):m) = if a==name then b else get name m instance HasEnv (M v) v where inNewEnv name v (M f) = M(\ st env -> f st ((name,v):env)) getfromEnv name = M h where h st env = (Just(get name env),[],st) instance HasStore (M v) v where getfromStore name = M h where h st env = (Just(get name st),[],st) putinStore name v = M h where h st env = (Just v,[],(name,v):st) instance Show v => Prints (M v) v where write message v = M h where h st env = (Just v,message++(show v),st) -------------------------------------------------------------- -- A state based algorithm data Tree a = Tip | Node (Tree a) a (Tree a) number :: Tree a -> Int -> (Tree (a,Int), Int) number Tip n = (Tip, n) number (Node l x r) n = (Node l' (x,n) r', n'') where (l',n') = number l (n+1) (r',n'') = number r n' --------------------------------------------------------------- -- Another example data Aop = Multiply | Add | Sub data Exp = Num Int | Var String | Oper (Exp, Aop, Exp ) | Let (String, Exp, Exp) e2 = Let("x",Num 5, Oper(Var "x", Add, Oper(Num 4,Multiply,Num 2))) -- free variables freeV :: Exp -> [ String] freeV term = freevars [] term [] where freevars bound x free = case x of Num(i) -> free Var(s) -> if any (==s) bound then free else add s free Oper(x,y,z) ->freevars bound x (freevars bound z free) Let(s,e,body) -> freevars (s:bound) body (freevars bound e free) add x [] = [x] add x xs = if any (==x) xs then xs else x:xs rename n x = x ++ (show n) find s [] = s find s ((t,v):xs) = if s==t then v else find s xs renameE x = snd(rnE [] 0 x) where rnE bnd n x = case x of Num(i) ->(n,Num i) Var(s) -> (n,Var(find s bnd)) Oper(x,y,z) -> let (n1,x') = rnE bnd n x (n2,z') = rnE bnd n1 z in (n2,Oper(x',y,z')) Let(s,e,b) -> let s' = rename n s (n1,b') = rnE ((s,s'):bnd) (n+1) b (n2,e') = rnE bnd n1 e in (n2,Let(s',e',b')) e3 = Let("x", Oper(Var "z",Multiply,Num 2), Let("q", Oper(Var "x",Add,Var "w"), Oper(Var "x",Sub, Oper(Var "q", Multiply,Var "v")))) e4 = renameE e3 {- Let ("x0", Oper (Var "z",Multiply,Num 2), Let ("q1", Oper (Var "x0",Add,Var "w"), Oper (Var "x0",Sub, Oper (Var "q1", Multiply,Var "v")))) -} ------------------------------------------------------ -- State in Haskell swap :: STRef s a -> STRef s a -> ST s () swap v w = do { x <- readSTRef v ; y <- readSTRef w ; writeSTRef w x ; writeSTRef v y } -- The Monadic Renaming Example rn bnd (Num i) v = return(Num i) rn bnd (Var s)v = return(Var(find s bnd)) rn bnd (Oper(x,y,z)) v = do { x' <- rn bnd x v ; z' <- rn bnd z v ; return(Oper(x',y,z')) } rn bnd (Let(s,e,b)) v = do { n <- readSTRef v ; writeSTRef v (n+1) ; s' <- return(rename n s) ; b' <- rn ((s,s'):bnd) b v ; e' <- rn bnd e v ; return(Let(s',e',b')) } re x = runST(do { v <- newSTRef 0; rn [] x v }) e5 = Let("x", Oper(Var "z",Multiply,Num 2), Let("q", Oper(Var "x",Add,Var "w"), Oper(Var "x", Sub, Oper(Var "q",Multiply,Var"v")))) e6 = re e5 ---------------------------------------------------------- -- Updateable linked lists type UpdList s a = STRef s (ListVar s a, ListVar s a) type ListVar s a = STRef s (ListElt s a) data ListElt s a = Nil | Cons a (ListVar s a) newList :: ST s (UpdList s a) newList = do {f <- newSTRef Nil; newSTRef (f,f)} frontList :: UpdList s a -> ST s a frontList l = do {(f,b) <- readSTRef l; Cons x f' <- readSTRef f; writeSTRef l (f',b); return x} backList :: UpdList s a -> a -> ST s () backList l x = do {(f,b) <- readSTRef l; b' <- newSTRef Nil; writeSTRef b (Cons x b'); writeSTRef l (f,b')} emptyList :: UpdList s a -> ST s Bool emptyList l = do {(f,b) <- readSTRef l; return (f == b)} --