Add HW1 solution.
This commit is contained in:
commit
02387bbf85
159
HW1.fedorind.hs
Normal file
159
HW1.fedorind.hs
Normal file
|
@ -0,0 +1,159 @@
|
|||
module HW1 where
|
||||
|
||||
|
||||
--
|
||||
-- * A simple arithmetic expression language
|
||||
--
|
||||
|
||||
-- | A representation of arithmetic expressions as binary trees where leaves
|
||||
-- are literal integers and internal nodes are either addition or
|
||||
-- multiplaction nodes. Note that this data structure is an "abstract
|
||||
-- syntax tree", which is something we will spend more time talking about
|
||||
-- later in the course.
|
||||
data Expr
|
||||
= Lit Int -- ^ Literal integers
|
||||
| Add Expr Expr -- ^ Addition expressions
|
||||
| Mul Expr Expr -- ^ Multiplication expressions
|
||||
deriving (Eq,Show)
|
||||
|
||||
instance Num Expr where
|
||||
(+) = Add
|
||||
(*) = Mul
|
||||
fromInteger = Lit . fromInteger
|
||||
|
||||
fold :: (Int -> a) -> (a -> a -> a) -> (a -> a -> a) -> Expr -> a
|
||||
fold f1 f2 f3 = rec
|
||||
where
|
||||
rec (Lit i) = f1 i
|
||||
rec (Add l r) = f2 (rec l) (rec r)
|
||||
rec (Mul l r) = f3 (rec l) (rec r)
|
||||
|
||||
-- | The expression: 2 + 3 * 4
|
||||
e1 :: Expr
|
||||
e1 = Add (Lit 2) (Mul (Lit 3) (Lit 4))
|
||||
|
||||
-- | The expression: (7 + 6) * 5
|
||||
e2 :: Expr
|
||||
e2 = Mul (Add (Lit 7) (Lit 6)) (Lit 5)
|
||||
|
||||
|
||||
-- | The expresssion: 3 * 2 + 5 * 4
|
||||
-- Make sure to take standard operator precedence into account.
|
||||
e3 :: Expr
|
||||
e3 = 3 * 2 + 5 * 4 -- :)
|
||||
|
||||
|
||||
-- | The expression: 8 + 7 * 9 + 6
|
||||
-- Make sure to take standard operator precedence into account.
|
||||
e4 :: Expr
|
||||
e4 = 8 + 7 * 9 + 6 -- :)
|
||||
|
||||
|
||||
-- | The leftmost literal in an expression.
|
||||
--
|
||||
-- >>> leftLit (Lit 3)
|
||||
-- 3
|
||||
--
|
||||
-- >>> leftLit e1
|
||||
-- 2
|
||||
--
|
||||
-- >>> leftLit e2
|
||||
-- 7
|
||||
--
|
||||
leftLit :: Expr -> Int
|
||||
leftLit = fold id const const
|
||||
|
||||
|
||||
-- | The rightmost literal in an expression.
|
||||
--
|
||||
-- >>> rightLit (Lit 3)
|
||||
-- 3
|
||||
--
|
||||
-- >>> rightLit e3
|
||||
-- 4
|
||||
--
|
||||
-- >>> rightLit e4
|
||||
-- 6
|
||||
--
|
||||
rightLit :: Expr -> Int
|
||||
rightLit = fold id (flip const) (flip const)
|
||||
|
||||
|
||||
-- | Get the maximum literal value in an expression.
|
||||
--
|
||||
-- >>> maxLit (Lit 3)
|
||||
-- 3
|
||||
--
|
||||
-- >>> maxLit e1
|
||||
-- 4
|
||||
--
|
||||
-- >>> maxLit e2
|
||||
-- 7
|
||||
--
|
||||
-- >>> maxLit e3
|
||||
-- 5
|
||||
--
|
||||
-- >>> maxLit e4
|
||||
-- 9
|
||||
--
|
||||
maxLit :: Expr -> Int
|
||||
maxLit = fold id max max
|
||||
|
||||
|
||||
-- | The integer result of evaluating an expression.
|
||||
--
|
||||
-- >>> eval (Lit 3)
|
||||
-- 3
|
||||
--
|
||||
-- >>> eval e1
|
||||
-- 14
|
||||
--
|
||||
-- >>> eval e2
|
||||
-- 65
|
||||
--
|
||||
-- >>> eval e3
|
||||
-- 26
|
||||
--
|
||||
-- >>> eval e4
|
||||
-- 77
|
||||
--
|
||||
eval :: Expr -> Int
|
||||
eval = fold id (+) (*)
|
||||
|
||||
|
||||
-- | Render an expression as a string (called "pretty printing").
|
||||
--
|
||||
-- My solution only adds parentheses when strictly necessary, but it's
|
||||
-- easier to add them conservatively (that is, to add more than you need).
|
||||
-- It's OK if your solution adds more parentheses as long as they don't
|
||||
-- change the meaning of the expression--feel free to tweak the tests to
|
||||
-- make them pass.
|
||||
--
|
||||
-- >>> pretty (Lit 3)
|
||||
-- "3"
|
||||
--
|
||||
-- >>> pretty e1
|
||||
-- "2 + 3 * 4"
|
||||
--
|
||||
-- >>> pretty e2
|
||||
-- "(7 + 6) * 5"
|
||||
--
|
||||
-- >>> pretty e3
|
||||
-- "3 * 2 + 5 * 4"
|
||||
--
|
||||
-- >>> pretty e4
|
||||
-- "8 + 7 * 9 + 6"
|
||||
--
|
||||
-- >>> pretty (Add e1 e2)
|
||||
-- "2 + 3 * 4 + (7 + 6) * 5"
|
||||
--
|
||||
-- >>> pretty (Mul e1 e2)
|
||||
-- "(2 + 3 * 4) * (7 + 6) * 5"
|
||||
--
|
||||
pretty :: Expr -> String
|
||||
pretty (Lit n) = show n
|
||||
pretty (Add l r) = pretty l ++ " + " ++ pretty r
|
||||
pretty (Mul l r) = prettyMul l ++ " * " ++ prettyMul r
|
||||
where
|
||||
prettyMul e@Add{} = "(" ++ pretty e ++ ")"
|
||||
prettyMul e = pretty e
|
Loading…
Reference in New Issue
Block a user