| 
    1module Expr0 where 
   2import ShowTree 
   3 
   4data Expr = Const Int 
   5          | Bin Op2 Expr Expr 
   6          | Un  Op1 Expr 
   7          deriving (Show) 
   8 
   9data Op2 = Add | Sub | Mul | Div 
  10         deriving (Show) 
  11 
  12data Op1 = Plus | Minus | Abs 
  13         deriving (Show) 
  14 
  15eval :: Expr -> Int 
  16eval (Const n)      = n 
  17eval (Bin op e1 e2) = apply2 op (eval e1) (eval e2) 
  18eval (Un  op e1)    = apply1 op (eval e1) 
  19 
  20apply2 :: Op2 -> (Int -> Int -> Int) 
  21apply2 Add = (+) 
  22apply2 Sub = (-) 
  23apply2 Mul = (*) 
  24apply2 Div = div 
  25 
  26apply1 :: Op1 -> (Int -> Int) 
  27apply1 Plus  = id 
  28apply1 Minus = \ x -> 0 - x 
  29apply1 Abs   = abs 
  30 
  31-- ---------------------------------------- 
  32-- 
  33-- example expr 
  34 
  35e1 :: Expr 
  36e1 = Bin Mul (Un Abs (Bin Sub (Const 1) 
  37                              (Const 8) 
  38                     ) 
  39             ) 
  40             (Bin Div (Const 13) 
  41                      (Const 2) 
  42             ) 
  43 
  44v1 :: Int 
  45v1 = eval e1 
  46 
  47-- ---------------------------------------- 
  48-- 
  49-- pretty printing expr 
  50 
  51prettyExpr :: Expr -> String 
  52prettyExpr (Const n)      = show n 
  53prettyExpr (Bin op e1 e2) = "(" 
  54                            ++ prettyExpr e1 
  55                            ++ " " 
  56                            ++ prettyOp2  op 
  57                            ++ " " 
  58                            ++ prettyExpr e2 
  59                            ++ ")" 
  60prettyExpr (Un  op e1)    = "(" 
  61                            ++ prettyOp1  op 
  62                            ++ prettyExpr e1 
  63                            ++ ")" 
  64 
  65prettyOp2 :: Op2 -> String 
  66prettyOp2 Add   = "+" 
  67prettyOp2 Sub   = "-" 
  68prettyOp2 Mul   = "*" 
  69prettyOp2 Div   = "`div`" 
  70 
  71prettyOp1 Plus  = "+" 
  72prettyOp1 Minus = "-" 
  73prettyOp1 Abs   = "abs " 
  74 
  75-- ---------------------------------------- 
  76-- 
  77-- pseudo graphical tree output for expr 
  78 
  79showExpr :: Expr -> String 
  80showExpr = formatStringNTree . toNTree 
  81  where 
  82    toNTree (Const n)       = NTree (show n) [] 
  83    toNTree (Bin op2 e1 e2) = NTree (show op2) [toNTree e1, toNTree e2] 
  84    toNTree (Un  op1 e1)    = NTree (show op1) [toNTree e1] 
  85 
  86printExpr :: Expr -> IO () 
  87printExpr = putStrLn . showExpr 
  88 
  89-- ---------------------------------------- 
 | 
    
| 
    1module Expr1 where 
   2import ShowTree 
   3 
   4data Expr a = Const a 
   5            | Bin Op2 (Expr a) (Expr a) 
   6            | Un  Op1 (Expr a) 
   7            deriving (Show) 
   8 
   9data Op2 = Add | Sub | Mul | Div 
  10         deriving (Show) 
  11 
  12data Op1 = Plus | Minus | Abs 
  13         deriving (Show) 
  14 
  15-- -------------------- 
  16-- 
  17-- functor instance for Expr 
  18 
  19mapExpr :: (a -> b) -> Expr a -> Expr b 
  20mapExpr f (Const n)      = Const (f n) 
  21mapExpr f (Bin op e1 e2) = Bin op (mapExpr f e1) (mapExpr f e2) 
  22mapExpr f (Un  op e1)    = Un  op (mapExpr f e1) 
  23 
  24instance Functor Expr where 
  25  fmap = mapExpr 
  26 
  27-- -------------------- 
  28-- 
  29-- the general evaluator 
  30 
  31eval :: (Op2 -> (a -> a -> a)) -> 
  32        (Op1 -> (a -> a)) -> 
  33        Expr a -> a 
  34eval apply2 apply1 e = eval' e 
  35  where 
  36    eval' (Const n)      = n 
  37    eval' (Bin op e1 e2) = apply2 op (eval' e1) (eval' e2) 
  38    eval' (Un  op e1)    = apply1 op (eval' e1) 
  39 
  40-- -------------------- 
  41-- 
  42-- integer arithmetic 
  43 
  44apply2i :: Integral a => Op2 -> (a -> a -> a) 
  45apply2i Add = (+) 
  46apply2i Sub = (-) 
  47apply2i Mul = (*) 
  48apply2i Div = div 
  49 
  50-- -------------------- 
  51-- 
  52-- fractional arithmetic 
  53 
  54apply2r :: Fractional a => Op2 -> (a -> a -> a) 
  55apply2r Add = (+) 
  56apply2r Sub = (-) 
  57apply2r Mul = (*) 
  58apply2r Div = (/) 
  59 
  60-- -------------------- 
  61-- 
  62-- common arithmetic 
  63 
  64apply1 :: Num a => Op1 -> (a -> a) 
  65apply1 Plus  = id 
  66apply1 Minus = \ x -> 0 - x 
  67apply1 Abs   = abs 
  68 
  69-- -------------------- 
  70-- 
  71-- two different evaluators 
  72 
  73evali :: Expr Integer -> Integer 
  74evali = eval apply2i apply1 
  75 
  76evalr :: Expr Double -> Double 
  77evalr = eval apply2r apply1 
  78 
  79-- ---------------------------------------- 
  80-- 
  81-- example expr 
  82 
  83e1 :: Num a => Expr a 
  84e1 = Bin Mul (Un Abs (Bin Sub (Const 1) 
  85                              (Const 8) 
  86                     ) 
  87             ) 
  88             (Bin Div (Const 13) 
  89                      (Const 2) 
  90             ) 
  91 
  92v1 :: Integer 
  93v1 = evali e1 
  94 
  95v2 :: Double 
  96v2 = evalr e1 
  97 
  98-- ---------------------------------------- 
  99 
 100e1' :: Expr String 
 101e1' = fmap show e1 
 102 
 103apply2s :: Op2 -> (String -> String -> String) 
 104apply2s Add = binToString "+" 
 105apply2s Sub = binToString "-" 
 106apply2s Mul = binToString "*" 
 107apply2s Div = binToString "/" 
 108 
 109binToString op s1 s2 = 
 110  "(" ++ s1 ++ " " ++ op ++ " " ++ s2 ++ ")" 
 111 
 112apply1s :: Op1 -> (String -> String) 
 113apply1s Plus  = unToString "+" 
 114apply1s Minus = unToString "-" 
 115apply1s Abs   = unToString "abs" 
 116 
 117unToString op s1 = 
 118      "(" ++ op ++ " " ++ s1 ++ ")" 
 119 
 120evals :: Expr String -> String 
 121evals = eval apply2s apply1s 
 122 
 123exprToString :: Show a => Expr a -> String 
 124exprToString = evals . fmap show 
 125 
 126-- ---------------------------------------- 
 127-- 
 128-- test output 
 129 
 130showExpr :: Show a => Expr a -> String 
 131showExpr = formatStringNTree . toNTree 
 132  where 
 133    toNTree (Const n)       = NTree (show n) [] 
 134    toNTree (Bin op2 e1 e2) = NTree (show op2) [toNTree e1, toNTree e2] 
 135    toNTree (Un  op1 e1)    = NTree (show op1) [toNTree e1] 
 136 
 137printExpr :: Show a => Expr a -> IO () 
 138printExpr = putStrLn . showExpr 
 139 
 140-- ---------------------------------------- 
 | 
    
| Letzte Änderung: 17.01.2018 | © Prof. Dr. Uwe Schmidt |