Difference between revisions of "FP Laboratory 9"

From Marek Běhálek Wiki
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)