Subato

State in Haskell

.


> module Zustand where > import Control.Monad.Trans.Maybe > import Control.Monad.Trans.Class > import Control.Monad > import Control.Monad.IO.Class > newtype Anweisung st r = Z (st -> (st,r)) > setvar :: String -> Integer -> Anweisung [(String,Integer)] Integer > setvar x v = Z (\env -> ((x,v):env,v)) > getvar :: String -> Anweisung [(String,Integer)] (Maybe Integer) > getvar x = Z (\env -> (env,lookup x env)) > ex1 = > let > Z anw1 = setvar "x" 17 > Z anw2 = setvar "y" 4 > Z anw3 = setvar "z" 2 > Z anw4 = getvar "x" > Z anw5 = getvar "y" > Z anw6 = getvar "z" > (st1,_) = anw1 [] > (st2,_) = anw2 st1 > (st3,_) = anw3 st2 > (st4,Just x) = anw4 st3 > (st5,Just y) = anw5 st4 > (st6,Just z) = anw6 st5 > in (st6,(x+y)*z) > undDann:: (Anweisung st r1) -> (Anweisung st r2) -> (Anweisung st r2) > (Z anw1) `undDann` (Z anw2) > = Z (\s -> let (s1,r1) = anw1 s > (s2,r2) = anw2 s1 > in (s2,r2) ) > ex2 = > let > Z anw123 = > setvar "x" 17 `undDann` > setvar "y" 4 `undDann` > setvar "z" 2 > Z anw4 = getvar "x" > Z anw5 = getvar "y" > Z anw6 = getvar "z" > (st3,_) = anw123 [] > (st4,Just x) = anw4 st3 > (st5,Just y) = anw5 st4 > (st6,Just z) = anw6 st5 > in (st6,(x+y)*z) > undMit::(Anweisung st r1)-> (r1 -> Anweisung st r2) -> (Anweisung st r2) > (Z st1) `undMit` fs > = Z (\s -> let (s1,r1) = st1 s > (Z anw2) = fs r1 > in anw2 s1) > ergebnis :: r -> Anweisung st r > ergebnis r = Z (\st -> (st,r)) > ex3 = > let > Z anws = > setvar "x" 17 `undDann` > setvar "y" 4 `undDann` > setvar "z" 2 `undDann` > getvar "x" `undMit` \(Just x) -> > getvar "y" `undMit` \(Just y) -> > getvar "z" `undMit` \(Just z) -> > ergebnis ((x+y)*z) > in anws [] > infixl 1 --> > infixl 1 ->- > (-->) = undDann > (->-) = undMit > ex4 = let > Z anws = > setvar "x" 17 --> > setvar "y" 4 --> > setvar "z" 2 --> > getvar "x" ->- \(Just x) -> > getvar "y" ->- \(Just y) -> > getvar "z" ->- \(Just z) -> > ergebnis ((x+y)*z) > in anws [] > (=:) = setvar > x !() = getvar x > ex5 = let > Z anws = > "x" =: 17 --> > "y" =: 4 --> > "z" =: 2 --> > "x"!() ->- \(Just x) -> > "y"!() ->- \(Just y) -> > "z"!() ->- \(Just z) -> > ergebnis ((x+y)*z) > in anws [] > run (Z stm) = stm [] > ex6 = > "x" =: 17 --> > "y" =: 4 --> > "z" =: 2 --> > "x"!() ->- \(Just x) -> > "y"!() ->- \(Just y) -> > "z"!() ->- \(Just z) -> > ergebnis ((x+y)*z) > instance Monad (Anweisung st) where > (>>) = undDann > (>>=) = undMit > return = ergebnis > instance Functor (Anweisung st) where > fmap f (Z st) = Z (\s -> let (s1,r1) = st s in (s1,f r1)) > instance Applicative (Anweisung st) where > pure = ergebnis > (Z gf) <*> (Z ga) > = Z (\s -> let (s1,f) = gf s > (s2,a) = ga s1 > in (s2,f a)) > ex7 = > "x" =: 17 >> > "y" =: 4 >> > "z" =: 2 >> > "x"!() >>= \(Just x)-> > "y"!() >>= \(Just y)-> > "z"!() >>= \(Just z)-> > return ((x+y)*z) > ex8 = do > "x" =: 17 > "y" =: 4 > "z" =: 2 > mx <- "x"!() > let (Just x) = mx > my <- "y"!() > let (Just y) = my > mz <- "z"!() > let (Just z) = mz > return ((x+y)*z) > eval1 env = do > x <- lookup "x" env > y <- lookup "y" env > z <- lookup "z" env > return ((x+y)*z) > bsp1 = do > x <- lookup "x" [("y",42),("x",17)] > y <- lookup "y" [("y",42),("x",17)] > z <- lookup "z" [("y",42),("x",17)] > return (x+y) > ex9 = do > "x" =: 17 > "y" =: 4 > "z" =: 2 > mx <- "x"!() > my <- "y"!() > mz <- "z"!() > return $do > x<-mx > y<-my > z<-mz > return ((x+y)*z) > ex10 :: MaybeT (Anweisung [(String,Integer)]) Integer > ex10 = do > MaybeT$fmap Just ("x" =: 17) > MaybeT$fmap Just ("y" =: 4) > MaybeT$fmap Just ("z" =: 2) > xm <- MaybeT ("x"!()) > ym <- MaybeT ("y"!()) > zm <- MaybeT ("z"!()) > return ((xm+ym)*zm) > ex11 :: MaybeT (Anweisung [(String,Integer)]) Integer > ex11 = do > lift ("x" =: 17) > lift ("y" =: 4) > lift ("z" =: 2) > xm <- MaybeT ("x"!()) > ym <- MaybeT ("y"!()) > zm <- MaybeT ("z"!()) > return ((xm+ym)*zm) > bsp2 = do > print "geben sie eine Zahl ein" > i <- (readLn::IO Integer) > print "das Quadrat ist" > print (i*i) > xs <- readFile "Zustand.lhs" > writeFile "newZust.hs" xs > bsp3 = do > x <- [1,2,3,4] > y <- [5,6,7] > return (x,y) > bsp4 = do > x <- [1,2,3,4] > y <- [5,6,7] > guard (x`mod`2==0) > return (x,y) > data Imperator = > Lese String > |Drucke Imperator > |Zuweisung String Imperator > |Literal Integer > |Var String > |Arith Imperator (Integer->Integer->Integer) Imperator > |While Imperator Imperator > |Sequenz [Imperator] > factorial = Sequenz > [Lese "x" > ,Zuweisung "r" (Literal 1) > ,While > (Var "x") > (Sequenz > [Zuweisung "r" (Arith (Var "r")(*)(Var "x")) > ,Zuweisung "x" (Arith (Var "x")(-)(Literal 1)) > ] > ) > ,Drucke (Var "r") > ] > newtype AnweisungT st m r > = AnweisungT {runAnweisungT::(st -> m (st, r))} > instance Monad m => Functor (AnweisungT st m) where > fmap f (AnweisungT anw) = AnweisungT (\x-> fmap (\(s',a)->(s', f a)) (anw x)) > instance Monad m => Monad (AnweisungT st m) where > return a = AnweisungT (\st -> return (st,a)) > (AnweisungT anw1) >>= k = AnweisungT $ \ s -> do > ~(s',a) <- anw1 s > let (AnweisungT anw2) = (k a) > anw2 s' > instance (Functor m, Monad m) => Applicative (AnweisungT st m) where > pure a = AnweisungT $ \ s -> return (s, a) > > AnweisungT mf <*> AnweisungT mx = AnweisungT $ \ s -> do > ~(s', f) <- mf s > ~(s'', x) <- mx s' > return (s'', f x) > m *> k = m >>= \_ -> k > instance MonadTrans (AnweisungT st) where > lift m = AnweisungT $ \ st -> do > a <- m > return (st, a) > instance (MonadIO m) => MonadIO (AnweisungT st m) where > liftIO io = lift (liftIO io) > liftAnweisung (Z f) = AnweisungT (\st -> return (f st)) > execute :: Imperator > -> MaybeT (AnweisungT [(String, Integer)] IO) Integer > execute (Literal n) = return 0 -- ToDo > execute (Var v) = do > return 0 -- ToDo > execute (Drucke imp) = do > return 0 -- ToDo > execute (Zuweisung v imp) = do > return 0 -- ToDo > execute (Lese v) = do > return 0 -- ToDo > execute (Arith l op r) = do > return 0 -- ToDo > execute w@(While cond body) = do > return 0 -- ToDo > execute (Sequenz [i]) = return 0 -- ToDo > execute (Sequenz (i:is)) = do > return 0 -- ToDo > execute (Sequenz []) = return 0
lhs