{--------------------------------------------------------------- Datei mit Beispieldefinitionen zu algebraischen Datenstrukturen ----------------------------------------------------------------} ------------------------ -- Aufzaehlungstypen -- ------------------------ data Tag = Montag | Dienstag | Mittwoch | Donnerstag | Freitag | Samstag | Sonntag deriving (Ord,Enum,Show) -- deriving Show -- Hinweis: -- Mittels deriving werden automatisch Grundfunktionen -- der genannten Typklassen hergeleitet und bereitgestellt -- Eq --> Gleichheitstest (==) :: Tag -> Tag -> Bool -- Ord --> Vergleichsoperatoren wie (<) :: Tag -> Tag -> Bool -- Enum --> Aufzaehlungsfunktionen enumFromTo :: a -> a -> [a] -- Show --> Anzeigefunktion show :: Tag -> String -- tagNr :: Tag -> Int tagNr tag = fromEnum tag + 1 nr2tag :: Int -> Tag nr2tag nr = head [tag | tag <- [Montag .. Sonntag], tagNr tag == nr] -- alternative Definition: nr2Tag nr = toEnum (nr-1) -- eigene Gleichheit, die Wochentage und Wochenendtage werden jeweils identifiziert instance Eq Tag where tag1 == tag2 = wochentag tag1 == wochentag tag2 where wochentag tag = tagNr tag `elem` [1..5] -- falsch ist: -- tag `elem` [Montag .. Freitag] -- data Farbe = Rot | Gruen | Gelb | Blau deriving (Eq,Ord,Enum,Show) {------------------ -- Verbundtypen -- ------------------ type Name = String type Vorname = String type Adresse = String type Alter = Int -- data Person = P Name Vorname Adresse Alter deriving Show alter :: Person -> Alter alter (P _ _ _ n) = n name :: Person -> Name name (P n _ _ _) = n --} type Personalliste = [Person] durchschnittsalter :: Personalliste -> Float durchschnittsalter [] = 0.0 durchschnittsalter ps = fromIntegral (sumAlter ps) / fromIntegral (length ps) sumAlter :: Personalliste -> Int sumAlter [] = 0 sumAlter (p:ps) = alter p + sumAlter ps pliste = [P "Null" "" "" 50, P "Eins" "" "" 30, P "Zwei" "" "" 25] ------------------- -- Record Syntax -- ------------------- -- besser lesbare Definition -- mit automatischer Erzeugung von Selektorfunktionen data Person = P { name :: String, vorname :: String, adresse :: String, alter :: Int } deriving (Show) pliste2 = [P {name = "Null", vorname = "", adresse ="", alter = 50}, P {name = "Eins", vorname = "", adresse ="", alter = 30}, P "Zwei" "" "" 25] --} ------------------ -- Binaerbaeume -- ------------------ data BinaryTree a = Leaf a | Node a (BinaryTree a)(BinaryTree a) deriving (Show) {- mit Record Syntax data BinaryTree a = Leaf { leaf :: a} | Node {value :: a, left :: (BinaryTree a), right :: (BinaryTree a) } deriving (Show) -} -- typische Baumfunktionen -- Eintraege inkrementieren incTree :: BinaryTree Int -> BinaryTree Int incTree (Leaf x) = Leaf (x+1) incTree (Node x l r) = Node (x+1) (incTree l) (incTree r) -- Eintraege verdoppeln doubleTree :: BinaryTree Int -> BinaryTree Int doubleTree (Leaf x) = Leaf (2*x) doubleTree (Node x l r) = Node (2*x) (doubleTree l) (doubleTree r) -- Eintraege aufsummieren sumTree :: BinaryTree Int -> Int sumTree (Leaf x) = x sumTree (Node x l r) = x + sumTree l + sumTree r -- minimalen Eintrag bestimmen minTree :: BinaryTree Int -> Int minTree (Leaf x) = x minTree (Node x l r) = min x (min (minTree l) (minTree r)) -- Baumtiefe bestimmen depth :: BinaryTree a -> Int depth (Leaf _) = 1 depth (Node x l r) = 1 + max (depth l) (depth r) baum :: BinaryTree Int baum = (Node 15 (Node 25 (Node 27 (Leaf 14) (Leaf 13)) (Node 20 (Leaf 15) (Leaf 5))) (Node 5 (Leaf 4) (Leaf 1))) -------------------------- -- Ausdrucksauswertung -- -------------------------- -- einfache arithmetische Ausdruecke data Expr = Lit Int | Add Expr Expr | Sub Expr Expr | Mult Expr Expr -- deriving Show -- Auswertungsfunktion eval :: Expr -> Int eval (Lit n) = n eval (Add e1 e2) = eval e1 + eval e2 eval (Sub e1 e2) = eval e1 - eval e2 eval (Mult e1 e2) = eval e1 * eval e2 -- Anzeigefunktion instance Show Expr where show (Lit n) = show n show (Add e1 e2) = '(': show e1 ++ "+" ++ show e2 ++ ")" show (Sub e1 e2) = '(': show e1 ++ "-" ++ show e2 ++ ")" show (Mult e1 e2) = '(': show e1 ++ "*" ++ show e2 ++ ")" e0 = Add (Mult (Sub (Lit 3) (Lit 5)) (Lit 2)) (Sub (Lit 3) (Lit 7)) -------------------------- -- Geometrische Formen -- -------------------------- data Shape = Rectangle Side Side | Ellipse Radius Radius | RtTriangle Side Side | Polygon [Vertex] deriving Show type Radius = Float type Side = Float type Vertex = (Float,Float) square :: Side -> Shape square s = Rectangle s s circle :: Radius -> Shape circle r = Ellipse r r area :: Shape -> Float area (Rectangle s1 s2) = s1*s2 area (RtTriangle s1 s2) = s1*s2/2 area (Ellipse r1 r2) = pi*r1*r2 area (Polygon (v1:vs)) = polyArea vs where polyArea :: [Vertex] -> Float polyArea (v2:v3:vs') = triArea v1 v2 v3 + polyArea (v3:vs') polyArea _ = 0 triArea :: Vertex -> Vertex -> Vertex -> Float triArea v1 v2 v3 = let a = distBetween v1 v2 b = distBetween v2 v3 c = distBetween v3 v1 s = 0.5*(a+b+c) in sqrt (s*(s-a)*(s-b)*(s-c)) -- pi ist vordefiniert -- pi :: Float -- pi = 3.14159 distBetween :: Vertex -> Vertex -> Float distBetween (x1,y1) (x2,y2) = sqrt ((x1-x2)^2 + (y1-y2)^2)