Haskell Funktionen

Werbung
Haskell Funktionen
Definieren Sie eine Funktion circleArea zur Berechnung der Fläche eines Kreises
mit gegebenen Radius (Float).
circleArea :: Float -> Float
circleArea radius = 2 * pi * radius^2
Definieren Sie zwei Funktionen min und max, die das Minimum bzw. Maximum
zweier Integers bestimmen.
min :: Integer -> Integer -> Integer
min x y = if x < y then x else y
max :: Integer -> Integer -> Integer
max x y = if x > y then x else y
Definieren Sie zwei Funktionen abs und signum, die den Absolutbetrag bzw. das
Vorzeichen einer Integer-Zahl berechnet.
abs :: Integer -> Integer
abs x = if x < 0 then -x else x
signum :: Integer -> Integer
signum x
| x == 0 = 0
|x<0
= -1
|x>0
=1
1
Definieren Sie eine Funktion fib, die die n-te Fibonacci-Zahl berechnet.
fib :: Integer -> Integer
fib n
| n == 0 = 1
| n == 1 = 1
| n >= 2 = fib(n-2) + fib(n-1)
| otherwise = error „fib mit negativem Argument aufgerufen“
Unendliche Liste der Fibonacci-Zahlen:
fib n m = n : (fib m (n+m))
fib1 n = (take1 n (fib 1 1))
take1 0 _ = []
take1 _ [] = []
take1 (n+1) (x : xs) = x : take1 n xs
take :: Int -> [a] -> a
take n (x : xs) = if n == 0 then x else take (n-1) xs
Definieren Sie zwei Funktionen even und odd für Integer.
even :: Integer -> Bool
even n = (n ‘mod’ 2 == 0)
odd :: Integer -> Bool
odd n = (n ‘mod’ 2 == 1)
-- noch einfacher ist
odd n = not (even n)
Definieren Sie eine Funktion eqMod, die testet, ob zwei Integer-Zahlen modulo n
gleich sind.
eqMod :: Integer -> Integer -> Integer -> Bool
eqMod x y n = ((x - y) ’mod’ n == 0)
-- äquivalent zu x ‘mod’ n == y ‘mod’ n
2
Definieren Sie eine Funktion hoch, die xn für Integer-Zahlen berechnet.
Verwenden Sie
1. rekursive Multiplikation mit x,
2. rekursive Quadrierung (xn = (x(n/2))2 für gerade n).
hoch1 :: Integer -> Integer -> Integer
hoch1 x n
|n>0
= x * hoch1 x (n-1)
| n == 0
=1
| otherwise = error “hoch1 mit negativem Exponenten“
hoch2 :: Integer -> Integer -> Integer
hoch2 x n
|n<0
= error “hoch1 mit negativem Exponenten“
| n == 0
=1
| even n
= (hoch2 x (n ’div’ 2))^2
| odd n
= x * hoch2 (n - 1)
Definieren Sie eine Funktion toUpper und eine Funktion toLower, die Kleinbuchstaben in
Großbuchstaben umwandelt bzw. umgekehrt. Jedes andere Zeichen soll unverändert bleiben.
--Beruht darauf, daß die Buchstaben des Alphabets in der (ASCII-)Codierung hintereinander --stehen
toUpper :: Char -> Char
toUpper c
| ‘a’ <= c && c <= ’z’
| otherwise
= char (ord c –ord ’a’ + ord ‘A’)
=c
toLower :: Char -> Char
toLower c
| ‘A’ <= c && c <= ’Z’
| otherwise
= char (ord c –ord ’A’ + ord ‘a’)
=c
Definieren Sie eine Funktion head, die das erste Zeichen eines Strings zurückgibt, und eine
Funktion tail, die das letzte Zeichen eines Strings bestimmt.
head :: String -> Char
head string = string !! 0
tail :: String -> Char
tail string = string !! (length string –1)
3
Definieren Sie eine Funktion swapT, die zwei boolsche Werte eines Tupels vertauscht.
swapT :: (Bool, Bool) -> (Bool, Bool)
swapT tupel = (snd tupel, fst tupel)
Definieren Sie eine Funktion sortT, die zwei boolsche Werte eines Tupels ordnet.
sortT :: (Bool, Bool) -> (Bool, Bool)
sortT tupel = if fst tupel > snd tupel then swapT tupel else tupel
Definieren Sie eine Funktion distance mit zwei Argumenten, die zu zwei Punkten in einem
zweidimensionalen Koordinatensystem (Datentyp Float) deren Abstand berechnet.
distance :: (Float, Float) -> (Float, Float) -> Float
distance point1 point2 = sqrt ((fst point1 – fst point2)^2 + (snd point1 – snd point2)^2
Definieren Sie eine Funktion xor, die das logische exklusive Oder berechnet.
1. Mit Patternmatching
2. Ohne Patternmatching
xor1 :: Bool -> Bool -> Bool
xor1 x y = x /= y
xor2 :: Bool -> Bool -> Bool
xor2 True True = False
xor2 False False = False
xor2 True False = True
xor2 false True = True
Definieren Sie eine Funktion toUpperStr und eine Funktion toLowerStr, die in einer ganzen
Zeichenkette Kleinbuchstaben in Großbuchstaben umwandelt bzw. umgekehrt.
toUpperStr :: String -> String
toUpperStr []
= []
toUpperStr (x : xs) = toUpper x : toUpperStr xs
toLowerStr :: String -> String
toLowerStr []
= []
toLowerStr (x : xs) = toLower x : toLowerStr xs
4
Definieren Sie eine Funktion elem, die prüft, ob ein Zeichen Element eines Strings ist.
elem :: Char -> String -> Bool
elem c [] = False
elem c (x:xs)
| c == x = True
| otherwise = elem c xs
Definieren Sie eine Funktion product, die alle Integers einer Liste miteinander multipliziert.
product :: [Integer] -> Integer
product []
=1
product (x : xs) = x * product xs
Definieren Sie eine Funktion sumOfLists, die zu einer Liste von Listen, deren Einträge vom
Typ Integer sind, die Summe der Listeneinträge berechnet.
sumOfLists :: [[Integer]] -> Integer
sumOfLists []
= []
sumOfLists (x : xs) = sum x : sumOfLists xs
Definieren Sie eine Funktion maxMinList, die in einem rekursiven Listendurchlauf das
Maximum und das Minimum einer Liste von Integers bestimmt.
maxMinList :: [Int] -> (Int, Int)
maxMinList [] = (minBound, maxBound)
--vordefiniert als kleinster und größter Wert des Typs.
--Fehlermeldung für leere Liste wäre hier auch sinnvoll.
maxMinList (x : xs) = (max x maxList, min x minList)
where
(maxList, minList) = maxMinList xs
5
Implementieren Sie Sortierfunktionen für Listen von Integers, mit den folgenden
Algorithmen:
• Insertion-Sort
• Bubble-Sort
• Merge-Sort
A) Insertion-Sort
insSort :: [Int] -> [Int]
insSort [] = []
insSort (x : xs) = insert x (insSort xs)
Einfügen einer Zahl an der der Ordnung entsprechenden Stelle.
insert :: Int -> [Int] -> [Int]
insert e [] = [e]
insert e (x : xs)
| e <= x = e : x :xs
| otherwise = x : insert e xs
B) Bubble-Sort
Einmaliges Durchlaufen der Liste mit Vertauschen falsch sortierter benachbarter Elemente.
bubble :: [Int] -> [Int]
bubble [] = []
bubble (x : []) = [x]
bubble (x : y : xs)
| y > x = y : bubble (x : xs)
| otherwise = x : bubble (y : xs)
bubbleSort :: [Int] -> [Int]
bubbleSort [] = []
bubbleSort xs = x : bubbleSort ys
where
(x : ys) = reverse (bubble xs)
C) Merge-Sort
Zusammenmischen zweier sortierter Listen.
merge :: [Int] -> [Int] -> [Int]
merge l1 [] = l1
merge [] = l2 = l2
merge (e1 : l1) (e2 : l2)
| e1 < e2 = e1 : merge l1 (e2 : l2)
| otherwise = e2 : merge (e1 : l1) l2
mergeSort :: [Int] -> [Int]
mergeSort [] = []
mergeSort [e] = [e]
mergeSort liste = merge (mergeSort links) (mergeSort rechts)
where
(links, rechts) = splitAt (length liste ’div’ 2) liste
6
Definieren Sie eine Funktion rotateL2 bzw. rotateL3, die die Elemente eines 2er bzw. 3er
Tupels um eine Stelle nach links rotiert.
rotateL2 :: (a, b) -> (b, a)
rotateL2 (x, y) = (y, x)
rotateL3 :: (a, b, c) -> (b, c, a)
rotateL3 (x, y, z) = (y, z, x)
Definieren Sie eine Funktion oddListEl, die aus einer Liste die Teilliste der Einträge mit
ungeradem Index herausfiltert und diese zurückgibt.
oddListEl :: [a] -> [a]
oddListEl [] = []
oddListEl [_] = []
oddListEl (x : y : zs) = y : oddListEl zs
Definieren Sie eine Funktion swapListEl, die die benachbarten Einträge einer Liste vertauscht,
d.h. den 1. mit dem 2., den 3. mit dem 4., usw.
swapListEl :: [a] -> [a]
swapListEl [x] = [x]
swapListEl (x : y : zs) = y : x : swapListEl zs
Definieren Sie eine Funktion concat, die eine Liste von Listen durch Aneinanderhängen zu
einer Liste verknüpft
concat :: [[a]] -> [a]
concat [] = []
concat (x : xs) = x ++ concat xs
7
Definieren Sie eine Funktion transpose, die eine Liste von Listen (gleicher Länge) als Matrix
auffasst und diese Matrix transponiert (Vertauschen von Zeilen und Spalten).
transpose :: [[a]] -> [[a]]
transpose ((x11 : x1s) : xss) = (x11 : heads) : conss x1s (transpose tails)
where
(heads, tails) = headTails xss
transpose _ = error “ Unterlisten nicht gleich lang in {transpose tails}“
conss :: [a] -> [[a]] -> [[a]]
conss [] [] = []
conss (x : xs) (ys : yss) = (x : ys) : conss xs yss
conss _ = error „Unterlisten nicht gleich lang in {transpose}“
headTails :: [[a]] -> ([a], [[a]])
headTails [] = ([], [])
headTails ((x : xs) : xss) = (x : ys, xs : yss)
where (ys, yss) = headTails xss
headTails _ = error “Unterlisten nicht gleich lang in {transpose}“
Definieren Sie einen Operator *_*, der das Quadrat des zweiten Arguments vom Quadrat des
ersten abzieht (Int-Zahlen). Testen Sie, welchen Unterschied es macht, diesen Operator als
links-, rechts- oder nicht assoziativ zu definieren.
Infixl 0 *-* -- hier auch infixr und infix ausprobieren
(*-*) :: Int -> Int -> Int
n *-* m = n^2 – m^2
-- zum Testen der Abhängigkeit von der Assiziativität:
x = 7 *-* 5 *-* 3
Definieren Sie eine Funktion permutations, die zu einer Liste die Liste aller Permutationen
dieser Liste bestimmt.
permutations :: [a] -> [[a]]
permutations []
= []
permutations (x : xs) = concat [insert x ys | ys <- permutations xs]
-- Einfuegen des ersten Argumentes in einer Liste.
-- Gibt eine Liste aller möglichen Ergebnislisten zurück.
insert :: a -> [a] -> [[a]]
insert x [] = [[x]]
insert x zs@ (y : ys) 0 (x : zs) : [y : inserted | inserted <- insert x ys]
8
Definieren Sie eine Funktion isPermutation mit zwei Argumenten, die testet, ob die eine IntListe eine Permutation der anderen Liste ist.
isPermutation :: [Int] -> [Int] -> Bool
isPermutation list1 list 2 = list1 ‘elem’ permutations list2
Definieren Sie eine Funktion powerList, die zu einer Liste die Liste aller Permutationen von
Teillisten erzeugt, die durch Streichen einiger Listenelemente entstehen (entspricht der
Potenzmenge, wenn die Liste eine Menge darstellt).
powerList :: [a] -> [[a]]
powerListn [] = [[]]
powerList (x : xs) = p ++ [x : y | y <- p]
where
p = powerList xs
Definieren Sie eine Funktion zipWith :: (a -> b -> c) -> [a] -> [b] -> [c], die die Elemente
zweier gleichlanger Listen durch eine Funktion paarweise verknüpft, und eine Funktion
zip :: [a] -> [b] -> [(a, b)], die zwei gleichlange Listen zu einer Liste von Paaren verknüpft.
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith z (a : as) (b : bs) = z a b : zipWith z as bs
zipWith _ _ _ = []
zip :: [a] -> [b] -> [(a, b)]
zip = zipWith (\a b -> (a, b))
Definieren Sie eine Funktion mapMat, die ein map auf Matrizen berechnet. Eine Matrix kann
durch eine Liste von Listen dargestellt werden.
mapMat :: (a -> b) -> [[a]] -> [[b]]
mapMat = map . map
Definieren Sie eine Funktion factors, die die Listen aller Faktoren einer Integer-Zahl
berechnet. Verwenden Sie hierbei die Funktion filter.
factors :: Integer -> [Integer]
factors n = filter divedsn [1 .. n]
where
divedsn m = n ‘mod’ m == 0
9
Definieren Sie eine Funktion unlines :: [String] -> String, die alle Strings einer Liste mit
einem Zeilenendzeichen \n versieht und aneinanderhängt, ohne Verwendung expliziter
Rekursion.
unlines :: [String] -> String
unlines = concat . map (\l -> l ++ “\n“)
Definieren Sie eine Funktion reverse unter Verwendung von foldl.
reverse :: [a] -> [a]
reverse = foldl (flip (:)) []
Definieren Sie eine Funktion length unter Verwendung von foldl.
length :: [a] -> Int
length = foldl (\n _ -> n + 1) 0
Definieren Sie eine Funktion unzip :: [(a, b)] -> ([a], [b]), die die Umkehrung von zip unter
Verwendung von foldr darstellt.
unzip :: [(a, b)] -> ([a], [b])
unzip = foldr (\(a, b) xs -> let (ax, bs) = xs in (a : as, b : bs)) ([], [])
Schreiben Sie eine Funktion square, die zu einem Parameter, der als Int übergeben wird, das
Quadrat berechnet und zurückliefert.
square :: Int -> Int
square x = x* x
Schreiben Sie eine Funktion cube, die den Kubik zu einem Integer berechnet.
cube :: Int -> Int
cube x = x + square x
Schreiben Sie eine Funktion allEqual, die überprüft, ob drei übergebene Integers gleich sind.
allEqual :: Int -> Int -> Int -> Bool
allEqual n m p = (n == m) && (m == p)
10
Schreiben Sie eine Funktion hcf, die den größten gemeinsamen Teiler von zwei Zahlen
bestimmt.
hcf :: Int -> Int -> Int
hcf n m
| n == m = n
| m > n = hcf m n
| otherwise = hcf (n – m) m
Zur besseren Strukturierung von Funktionsdefinitionen können sogenannte lokale
Definitionen verwendet werden. Zum Beispiel:
maxSquare n m
| sqN > sqM = sqN
| otherwise = sqM
where
sqN = square n
sqM = square m
square :: Int -> Int
square z = z*z
Schreiben Sie eine Funktion sumList, die eine Liste von Integern bekommt und die Summe
der Integer aus der Liste als Ergebnis zurückliefert.
sumList :: [Int] -> Int
sumList [] = 0
sumList (a : xs) = a + sumList x
Schreiben Sie eine Funktion double, die zu einer Liste von Integern eine Liste berechnet, die
zu jedem Eintrag das Doppelte enthält.
double :: [Int] -> [Int]
double [] = []
double (a : xs) = (2 * a) : double x
Schreiben Sie eine Funktion append, die zwei Listen von Integern zu einer Liste verkettet.
append :: [Int] -> [Int] -> [Int]
append [] y 0 y
append (a : x) y = a : (append x y)
11
Schreibe eine Funktion, die eine Liste von Zahlen sortiert. Verwende dazu den folgenden
rekursiven Algorithmus (Insertsort):
Wenn [a1, ..., an] die zu sortierende Liste ist, dann sortiere die Liste [a2, ..., an] und füge das
Element a1 an der passenden Stelle ein.
iSort :: [Int] -> [Int]
iSort [] = []
iSort (a : x) = ins a (iSort x)
ins :: Int -> [Int] -> [Int]
ins a [] = [a]
ins a (b : y)
| a <= b = a : (b : y)
| otherwise = b : ins a y
Die Funktion map nimmt ein Argument vom Typ Int -> Int und liefert eine Funktion vom
Typ [Int] -> [Int] als Ergebnis. Damit lässt sich zum Beispiel sehr einfach aus einer Liste von
Zahlen eine Liste der mit 2 multiplizierten Zahlen konstruieren.
map :: (Int -> Int) -> [Int] -> [Int]
map f [] = []
map f (a : x) = (f a) : (map f x)
double :: Int -> Int
double x = 2 * x
map double [1, 2, 4]
= (double 2) : (map double [1, 4])
= (double 2) : ((double 1) map double [4])
= (double 2) : ((double 1) : ((double 4) (map double [])))
= (double 2) : ((double 1) : ((double 4) []))
= 4 : (2 : (8 : []))
= 4 : (2 : [8])
= 4 : [2, 8]
= [4 : 2 : 8]
Möchten wir jetzt auf die Listenelemente eine andere Funktion anwenden, so braucht man
diese nur zu definieren und als erstes Argument von map anzugeben. Die Funktion map wirkt
also wie eine Art von benutzerdefinierter Kontrollstruktur.
12
Allgemeine Definition von map:
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs
Mit map kann eine Funktion vom Typ a -> zu einer Funktion vom Typ [a] -> [b] erweitert
werden. Die Funktion map ist parametrisch polymorph, d.h. sie wirkt auf gleiche Weise auf
ihre Argumentliste, völlig unabhängig davon, welchen Typ für a oder b eingesetzt wird.
Ausgehend von einem Startwert werden die Elemente von rechts nach links mit einem
zweistelligen Operator behandelt. Beide Funktionen ersetzen die leere Liste durch den
Startwert und den Listenkonstruktor durch eine zweistellige Funktion. Bei der zu
definierenden Funktion höherer Ordnung müssen daher ein Startwert e sowie eine Funktion f,
die anstelle des Listenkonstruktors angewendet wird, als Parameter auftreten.
Die Funktion foldr geht über map hinaus, indem sie die Ergebnisse von f faltet.
foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int
foldr f a [] = a
foldr f a (b : x) = f b (foldr f a x)
Allgemeiner:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f e [] = e
foldr f e (x.xs) = x `f` foldr f e xs
Die Funktion foldr klammert von rechts nach links.
Alternativ dazu gibt es die Funktion foldl, die in umgedrehter Richtung klammert.
foldl :: (a -> b -> a) -> a -> [b] -> a
foldl f e [] = e
foldl f e (x : xs) = foldl f (e `f` x) xs
Wie kann mittels foldr die Summe oder das Produkt der Zahlen einer Liste programmiert
werden?
sumList :: [Int] -> Int
sumList = foldr (+) 0 list
prodList :: [Int] -> Int
prodList list = foldr (*) 1 list
13
Schreiben Sie eine Funktion filter, die aus einer Liste von Zahlen solche mit einer bestimmten
Eigenschaft herausfiltert.
filter :: (Int -> Bool) -> [Int] -> [Int]
filter p [] = []
filter p (a : x)
| (p a) = a : (filter p x)
| otherwise = filter p x
Der Quicksort Algorithmus zum Sortieren einer Liste von Zahlen ist ein weiteres Beispiel für
die Benutzung von Funktionen höherer Ordnung.
quicksort :: [Int] -> [Int]
smaller :: Int -> Int -> Bool
smaller a b = (b < a)
greq :: Int -> Int -> Bool
greq a b = (b >= a)
quicksort [] = []
quicksort (a : x) = quicksort (filter (smaller a) x) ++ [a] ++ quicksort (filter (greq a) x)
--oder:
quicksort [] = []
quicksort (x:l) = quicksort (filter ( <x ) l ) ++ [x] ++quicksort(filter(>=x)l)
Komposition von Funktionen.
Funktionen lassen sich komponieren:
compose :: (Int -> Int) -> (Int -> Int) -> (Int -> Int)
compose f g x = (f (g x))
Für die Funktionskomposition gibt es in Haskell ein Symbol: (f . g) x = (f (g x))
Die Funktion length mit Typvariablen.
length :: [t] -> Int
length [] = 0
length (a : x) = 1 + (length x)
Hier ist t eine Typvariable, die mit einem beliebigen Typ instanziiert werden kann. Im
Unterschied zur Typbezeichnung beginnt der Name der Typvariablen immer mit einem
kleinen Buchstaben. Der Typ von length heißt polymorpher Typ, weil er verschiedene
Gestalten annehmen kann. Wird length in einem konkreten Kontext benutzt, so wird die
Typvariable t entsprechend instanziiert.
14
Auch andere nützliche Listenfunktionen hängen nicht vom Typ der Elemente ab und sollten
sofort polymorph definiert werden.
append :: [t] -> [t] -> [t]
append [] l = l
append (a : x) l = a : (append x l)
zip :: [t] -> [u] -> [(t, u)]
zip [] [] = []
zip (a : x) [] = []
zip [] (b : y) = []
zip (a : x) (b : y) = (a, b) : (zip x y)
map :: (t -> t) -> [t] -> [t]
map f [] = []
map f (a : x) = (f a) : (map f x)
Schreiben Sie eine Funktion height, die zu dem folgenden Baum:
data Tree t = Nil | Node t (Tree t) (Tree t)
die Höhe (d.h. maximale Länge von Pfaden) berechnet.
height :: Tree t -> Int
height Nil
=1
height (Node n t1 t2) = 1 + (max (height t1) (height t2))
Die Funktion height berechnet die Höhe (d.h. maximale Länge von Pfaden) eines vorgelegten
Baums. Welchen Typ die Knotenwerte haben spielt keine Rolle.
Schreiben Sie eine Funktion collapse, die den folgenden Baum:
data Tree t = Nil | Node t (Tree t) (Tree t)
„inorder“ durchläuft und die Knotenbeschriftungen ausgibt.
collapse :: Tree t -> [t]
collapse Nil
= []
collapse (Node n t1 t2) = (collapse t1) ++ [n] ++ (collapse t2)
Die Funktion collapse durchläuft den vorgelegten Baum „inorder“ und gibt die
Knotenbeschriftungen aus.
15
Listenfunktionen:
ins
:: Ord a => a -> [a] -> [a]
x `ins` [] = [x]
x `ins` (y:ys)
| x <= y = x:y:ys
| x > y = y:(x `ins` ys)
merge
:: Ord a => [a] -> [a] -> [a]
xs `merge` [] = xs
[] `merge` ys = ys
(x:xs) `merge` (y:ys)
| x<=y = x : (xs `merge` (y:ys))
| x> y = y : ((x:xs) `merge` ys)
asList :: a -> [a]
asList x = [x]
liste :: Ord a => Tree a -> [a]
liste = foldTree insmerge asList
where
insmerge x ys zs = (x `ins` ys) `merge` zs
listeUnSort :: Tree a -> [a]
listeUnSort = foldTree consapp asList
where
consapp x ys zs = (x:ys) ++ zs
16
Baumdeklarationen:
data Tree t = Leaf t | Branch t (Tree t) (Tree t)
--oder
data Tree a = Leaf a | Node a (Tree a) (Tree a)
Die Funktionen foldTree und mapTree:
Die Funktion mapTree wendet eine Funktion auf alle Knotenbeschriftungen eines Bames
an. Die Funktion foldTree nimmt eine Funktion f als Parameter und ersetzt jedes
Vorkommen des Datenkonstruktors Node durch f, nachdem foldTree f über die Liste der
direkten Teilbäume gemappt worden ist.
foldTree :: (a -> b -> b -> b) -> (a -> b) -> Tree a -> b
foldTree _ g (Leaf x)
=gx
foldTree f g (Branch x l r) = f x (foldTree f g l) (foldTree f g r)
mapTree :: (a->b) -> Tree a -> Tree b
mapTree f = foldTree (\x l r -> Branch (f x) l r) (\x -> Leaf (f x))
--oder
data Tree element = Node element [Tree element]
mapTree :: (a -> b) -> Tree a -> Tree b
mapTree f (Node x subtrees) = Node (f x) (map (mapTree f) subtrees)
foldTree :: (a -> [b] -> b) -> Tree -> a -> b
foldTree f (Node x subtrees) = f x (map (foldTree f) subtrees)
17
Baumfunktionen:
-- Darstellung eines Baumes:
showTree :: Show a => Tree a -> String
showTree = foldTree showB showL
where
showL
= ("Leaf " ++) . show
showB x l r = "Branch " ++ show x ++ " (" ++ l ++ ") (" ++ r ++ ")"
instance Show a => Show (Tree a) where show = showTree
--Verdopplung aller Baumeinträge:
doubleTree :: Tree Int -> Tree Int
doubleTree (Leaf x) = Leaf (2*x)
doubleTree (Node x l r) = Node (2*x) (doubleTree l) (doubleTree r)
--Summation aller Baumeinträge:
sumTree :: Tree Int -> Int
sumTree (Leaf x) = x
sumTree (Node x l r) = x + (sumTree l) + (sumTree r)
--Bestimmung der minimalen Beschriftung:
minTree :: Tree Int -> Int
minTree (Leaf x) = x
minTree (Node x l r) = min x (min(minTree l) (minTree r ))
--Bestimmung der Baumtiefe:
depthTree :: Tree Int -> Int
depthTree (Leaf x ) = l
depthTree (Node x l r) = 1 + max(depthTree l) (depthTree r)
18
Herunterladen