Difference between revisions of "FP Laboratory 9"
Jump to navigation
Jump to search
Line 13: | Line 13: | ||
* Create function eval that evaluates expresions. | * Create function eval that evaluates expresions. | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution"> | ||
+ | <syntaxhighlight lang="Haskell"> | ||
+ | eval :: Expr -> Int | ||
+ | eval (Num x) = x | ||
+ | eval (Add l r) = (eval l) + (eval r) | ||
+ | eval (Sub l r) = (eval l) - (eval r) | ||
+ | eval (Mul l r) = (eval l) * (eval r) | ||
+ | eval (Div l r) = (eval l) `div` (eval r) | ||
+ | </syntaxhighlight> | ||
+ | </div> | ||
+ | <div style="clear:both"></div> | ||
+ | |||
* Create function showExpr that shows expression as a String. | * Create function showExpr that shows expression as a String. | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution"> | ||
+ | <syntaxhighlight lang="Haskell"> | ||
+ | showExpr :: Expr -> String | ||
+ | showExpr expr = showExpr' expr NoOp | ||
+ | |||
+ | data Operation = Hi | HiDiv | Lo | LoSub | NoOp deriving (Eq) | ||
+ | |||
+ | showExpr' :: Expr -> Operation -> String | ||
+ | showExpr' (Num x) _ = show x | ||
+ | showExpr' (Var x) _ = [x] | ||
+ | showExpr' (Add l r) op = let | ||
+ | x = showExpr' l Lo ++"+"++showExpr' r Lo | ||
+ | in if op == Hi || op == HiDiv || op==LoSub | ||
+ | then "(" ++ x ++")" | ||
+ | else x | ||
+ | showExpr' (Sub l r) op = let | ||
+ | x = showExpr' l Lo ++"-"++showExpr' r LoSub | ||
+ | in if op == Hi || op == HiDiv || op==LoSub | ||
+ | then "(" ++ x ++")" | ||
+ | else x | ||
+ | showExpr' (Mul l r) op = let | ||
+ | x = showExpr' l Hi ++"*"++showExpr' r Hi | ||
+ | in if op == HiDiv | ||
+ | then "(" ++ x ++")" | ||
+ | else x | ||
+ | showExpr' (Div l r) _ = showExpr' l Hi ++"/"++showExpr' r HiDiv | ||
+ | </syntaxhighlight> | ||
+ | </div> | ||
+ | <div style="clear:both"></div> | ||
+ | |||
* Extend class Show to be usable with our expressions. | * Extend class Show to be usable with our expressions. | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution"> | ||
+ | <syntaxhighlight lang="Haskell"> | ||
+ | instance (Show Expr) where | ||
+ | show = showExpr | ||
+ | </syntaxhighlight> | ||
+ | </div> | ||
+ | <div style="clear:both"></div> | ||
+ | |||
* Create function derivation representing symbolic derivation of a given expression. | * Create function derivation representing symbolic derivation of a given expression. | ||
+ | |||
+ | <div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution"> | ||
+ | <syntaxhighlight lang="Haskell"> | ||
+ | deriv :: Expr-> Char -> Expr | ||
+ | deriv (Num _) _ = (Num 0) | ||
+ | deriv (Var x) y | x==y = (Num 1) | ||
+ | | otherwise = (Num 0) | ||
+ | deriv (Add l r) x = Add (deriv l x) (deriv r x) | ||
+ | deriv (Sub l r) x = Sub (deriv l x) (deriv r x) | ||
+ | deriv (Mul l r) x = Add (Mul (deriv l x) r) (Mul l (deriv r x)) | ||
+ | deriv (Div l r) x = | ||
+ | Div | ||
+ | (Sub (Mul (deriv l x) r) (Mul l (deriv r x))) | ||
+ | (Mul r r) | ||
+ | </syntaxhighlight> | ||
+ | </div> | ||
+ | <div style="clear:both"></div> |
Revision as of 09:52, 24 September 2020
User defined data types and type classes
Consider following representation of expressions
data Expr = Num Int
| Add Expr Expr
| Sub Expr Expr
| Mul Expr Expr
| Div Expr Expr
| Var Char
deriving (Eq)
- Create function eval that evaluates expresions.
eval :: Expr -> Int
eval (Num x) = x
eval (Add l r) = (eval l) + (eval r)
eval (Sub l r) = (eval l) - (eval r)
eval (Mul l r) = (eval l) * (eval r)
eval (Div l r) = (eval l) `div` (eval r)
- Create function showExpr that shows expression as a String.
showExpr :: Expr -> String
showExpr expr = showExpr' expr NoOp
data Operation = Hi | HiDiv | Lo | LoSub | NoOp deriving (Eq)
showExpr' :: Expr -> Operation -> String
showExpr' (Num x) _ = show x
showExpr' (Var x) _ = [x]
showExpr' (Add l r) op = let
x = showExpr' l Lo ++"+"++showExpr' r Lo
in if op == Hi || op == HiDiv || op==LoSub
then "(" ++ x ++")"
else x
showExpr' (Sub l r) op = let
x = showExpr' l Lo ++"-"++showExpr' r LoSub
in if op == Hi || op == HiDiv || op==LoSub
then "(" ++ x ++")"
else x
showExpr' (Mul l r) op = let
x = showExpr' l Hi ++"*"++showExpr' r Hi
in if op == HiDiv
then "(" ++ x ++")"
else x
showExpr' (Div l r) _ = showExpr' l Hi ++"/"++showExpr' r HiDiv
- Extend class Show to be usable with our expressions.
instance (Show Expr) where
show = showExpr
- Create function derivation representing symbolic derivation of a given expression.
deriv :: Expr-> Char -> Expr
deriv (Num _) _ = (Num 0)
deriv (Var x) y | x==y = (Num 1)
| otherwise = (Num 0)
deriv (Add l r) x = Add (deriv l x) (deriv r x)
deriv (Sub l r) x = Sub (deriv l x) (deriv r x)
deriv (Mul l r) x = Add (Mul (deriv l x) r) (Mul l (deriv r x))
deriv (Div l r) x =
Div
(Sub (Mul (deriv l x) r) (Mul l (deriv r x)))
(Mul r r)