Difference between revisions of "FP Laboratory 9/cs"

From Marek Běhálek Wiki
Jump to navigation Jump to search
(Created page with "FP Cvičení 9")
 
(Updating to match new version of source page)
 
(6 intermediate revisions by one other user not shown)
Line 1: Line 1:
== User defined data types and type classes ==  
+
== Uživatelsky definované datové typy a typové třídy ==  
  
 
<div style="float: right"> [[File:Video logo.png|80px|link=https://youtu.be/lo0pdwWoSx4]]</div>  
 
<div style="float: right"> [[File:Video logo.png|80px|link=https://youtu.be/lo0pdwWoSx4]]</div>  
  
Consider following representation of expressions
+
Uvažujte následující reprezentaci výrazů
  
 
<syntaxhighlight lang="Haskell">
 
<syntaxhighlight lang="Haskell">
Line 15: Line 15:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
* Create function eval that evaluates expresions.  
+
* Implementujte funkci eval, která vyhodnocuje výrazy.  
  
 
<div style="float: right"> [[File:Video logo.png|80px|link=https://youtu.be/AvThE0I4Iz8]]</div>  
 
<div style="float: right"> [[File:Video logo.png|80px|link=https://youtu.be/AvThE0I4Iz8]]</div>  
Line 41: Line 41:
 
<div style="clear:both"></div>
 
<div style="clear:both"></div>
  
* Create function showExpr that shows expression as a String.  
+
* Implementujte funkci showExpr, která převede výraz na String.  
  
 
<div style="float: right"> [[File:Video logo.png|80px|link=https://youtu.be/cPL1zEZHLh0]]</div>  
 
<div style="float: right"> [[File:Video logo.png|80px|link=https://youtu.be/cPL1zEZHLh0]]</div>  
Line 83: Line 83:
 
     else x
 
     else x
 
showExpr' (Div l r) op = let
 
showExpr' (Div l r) op = let
   x = showExpr' l Hi ++"/"++showExpr' r Hi
+
   x = showExpr' l Hi ++"/"++showExpr' r HiDiv
 
   in if op == HiDiv
 
   in if op == HiDiv
 
     then "(" ++ x ++")"
 
     then "(" ++ x ++")"
Line 92: Line 92:
 
<div style="clear:both"></div>
 
<div style="clear:both"></div>
  
* Extend class Show to be usable with our expressions.
+
* Rozšiřte třídu Show tak, aby ji bylo možno využít s našimi výrazy.
  
 
<div style="float: right"> [[File:Video logo.png|80px|link=https://youtu.be/NCAxJx_wJxI]]</div>  
 
<div style="float: right"> [[File:Video logo.png|80px|link=https://youtu.be/NCAxJx_wJxI]]</div>  
Line 115: Line 115:
 
<div style="clear:both"></div>
 
<div style="clear:both"></div>
  
* Create function derivation representing symbolic derivation of a given expression.
+
* Implementujte funkci derivation reprezentující symbolickou derivaci daného výrazu.
 
   
 
   
 
<syntaxhighlight lang="Haskell">
 
<syntaxhighlight lang="Haskell">

Latest revision as of 07:41, 15 November 2021

Uživatelsky definované datové typy a typové třídy

Video logo.png

Uvažujte následující reprezentaci výrazů

data Expr = Num Int
          | Add Expr Expr
          | Sub Expr Expr
          | Mul Expr Expr
          | Div Expr Expr
          | Var Char
	  deriving (Eq)
  • Implementujte funkci eval, která vyhodnocuje výrazy.
Video logo.png
eval :: Expr -> Int
*Main> eval (Add (Num 1) (Num 2))
3
*Main> eval (Mul (Add (Num 1) (Num 2)) (Num 3))
9
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)
Try it!
  • Implementujte funkci showExpr, která převede výraz na String.
Video logo.png
showExpr :: Expr -> String
*Main> showExpr (Add (Num 1) (Num 2))
"1+2"
*Main> showExpr (Mul (Add (Num 1) (Num 2)) (Num 3))
"(1+2)*3"
*Main> showExpr (Mul (Add (Num 1) (Mul (Num 2) (Var 'x'))) (Mul (Num 3) (Var 'x')))
"(1+2*x)*3*x"
*Main> showExpr (Mul (Num 2) (Mul (Var 'x') (Var 'x')))                            
"2*x*x"
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) op = let
  x = showExpr' l Hi ++"/"++showExpr' r HiDiv
  in if op == HiDiv
     then "(" ++ x ++")"
     else x
Try it!
  • Rozšiřte třídu Show tak, aby ji bylo možno využít s našimi výrazy.
Video logo.png
*Main> Add (Num 1) (Num 2)
"1+2"
*Main> Mul (Add (Num 1) (Num 2)) (Num 3)
"(1+2)*3"
*Main> Mul (Add (Num 1) (Mul (Num 2) (Var 'x'))) (Mul (Num 3) (Var 'x'))
"(1+2*x)*3*x"
*Main> Mul (Num 2) (Mul (Var 'x') (Var 'x'))           
"2*x*x"
instance (Show Expr) where
  show = showExpr
Try it!
  • Implementujte funkci derivation reprezentující symbolickou derivaci daného výrazu.
deriv :: Expr-> Char -> Expr
*Main> deriv (Add (Num 1) (Num 2)) 'x'
0+0
*Main> deriv (Mul (Num 2) (Mul (Var 'x') (Var 'x'))) 'x'
0*x*x+2*(1*x+x*1)
*Main> deriv (Mul (Num 2) (Mul (Var 'x') (Var 'x'))) 'x'
0*x*x+2*(1*x+x*1)
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)
Try it!