Konzepte der Programmierung Programmierkurs 2 Sommer 2016 Universität Konstanz Informatik & Informationswissenschaft Marc Scholl, Stefan Klinger 9. Übungsblatt (Ausgabe: 6. Juni 2016 — Abgabe bis: 13. Juni 2016, 15:00 Uhr) Aufgabe 1 (3 Punkte) In der Vorlesung wurde auf Folie 269 der Datentyp BinTree α definiert. Schreiben Sie eine Funktion levels :: BinTree a -> [[a]] Diese soll eine Abwandlung der auf Folie 285 definierten Funktion levelorder sein. Auch hier ist eine ebenenweise Auflistung der Elemente des Baumes gewünscht, aber jede Ebene soll in einer eigenen Liste aufgesammelt sein, so daß die Eigenschaft levelorder ≡ concat . levels gilt. Es ist nicht nötig diese Eigenschaft zu beweisen. Achten Sie darauf keine leeren Ebenen auszugeben. Aufgabe 2 (2+2+3 Punkte) data LExpr = Var String | App LExpr LExpr | Lam String LExpr deriving (Eq, Show) Nochmal LExpr vom 7. Programmierkurs1 : -- Variable -- Funktionsapplikation -- Lambda-Abstraktion 1. Schreiben Sie eine Funktion lfold :: (String -> a) -> (a -> a -> a) -> (String -> a -> a) -> LExpr -> a welche die allgemeine Idee eines Folds für den Datentyp LExpr umsetzt. 2. Schreiben Sie dann die im Programmierkurs besprochenen Funktionen free und bindings mit lfold als einfache Einzeiler. 3. Schreiben Sie die Funktion bound vom letzten Übungsblatt mit lfold. Aufgabe 3 (6 Punkte) Machen Sie den Datentyp LExpr (Aufgabe 2) durch eine eigene Implementation (also nicht via deriving) zur Instanz von Show, so dass im Haskell Interpreter z.B. Folgendes funktioniert: Main> App (Lam "x" (App (Var "x") (Var "x"))) (Var "y") (\x -> x x) y Achten Sie auf eine “schöne” Ausgabe. Variablen sollen durch ihren Namen, die Funktionsapplikation durch Juxtaposition und die Lambda-Abstraktion unter Verwendung der Zeichen ’\’ und ’->’ dargestellt werden. Klammern sollen genau dann eingefügt werden, wenn dies nötig ist. Hinweis: Auch wenn das zunächst komplizierter aussieht: Implementieren Sie die Funktion showsPrec statt show, das ist letztendlich leichter! 1 https://svn.uni-konstanz.de/dbis/inf2_16s/pub/pk2-07.lhs 1 Aufgabe 4 (4+1+2 Punkte) Eine partielle Ordnung (≺) ist eine Relation die —im Gegensatz zur Totaleordnung— nicht zwischen allen Elementen der Trägermenge definiert ist. Zum Beispiel ist die “substring”-Beziehung eine partielle Ordnung auf Listen, denn es kann einer der folgenden vier Fälle eintreten: • x = y also Gleichheit, "foo" = "foo" • x ≺ y also x kleiner y, "foo" ≺ "foobar" • x y also x größer y, "foo" "oo" • weder noch. "foo" und "bar" Die Aufgaben: 1. Implementieren Sie eine Klasse POrd für partielle Ordnungen mit sinnvollen default-Definitionen. Orientieren Sie sich dabei an der Klasse Ord auf Folie 318. Die Klasse soll mindestens die folgenden Funktionen beinhalten (~<), (~>), (~<=), (~>=) :: a -> a -> Bool pcompare :: a -> a -> Maybe Ordering so daß gilt x ~< y ⇔ x ≺ y, und analog für die anderen binären Operatoren. pcompare x y soll, analog zu compare, angeben in welcher Ordnung x und y zueinander stehen. 2. Geben Sie die Minimal Complete Definition für Ihre Implementation der Klasse an. 3. Implementieren Sie die “substring”-Beziehung aus dem Beispiel oben für alle geeigneten Listen, d.h., machen Sie [α] partiell anordenbar bzgl. der substring-Beziehung (Sie dürfen natürlich substring aus der letzten Besprechung2 verwenden). 2 https://svn.uni-konstanz.de/dbis/inf2_16s/pub/solution06.lhs