Typklassen, Eingabe und Monaden In Haskell
|
|
- Miriam Rosenberg
- vor 7 Jahren
- Abrufe
Transkript
1 Typklassen, Eingabe und Monaden In Haskell Felix Rahmati Jonathan Beierle 1 Einleitung In dieser Ausarbeitung befassen wir uns mit den Vorteilen einiger fortgeschrittener Konzepte der funktionalen Programmierung und welche Vorteile diese mit sich bringen. 1.1 Rückblick: Funktionale Programmiersprachen Funktionale Programmiersprachen unterscheiden sich auf den ersten Blick sehr von imperativen und objektorientierten Sprachen wie Java. Unterschiede erkennt man im Aufbau der Programme. Im Gegensatz zu imperativen Programmen findet man in einem funktionalen Programm keine Schleifen. Stattdessen wird ausschließlich mit Rekursion gearbeitet. Außerdem besitzen Klassen und Objekte in der funktionalen Programmierung nicht immer dieselbe Bedeutung, wie in der objektorientierten Programmierung. Des Weiteren gibt man dem Compiler in der imperativen Programmierung einen festen Programmablauf vor, welcher nach und nach abgearbeitet werden muss, während in einem funktionalen Programm lediglich bestimmt wird, was in einem bestimmten Zustand passieren soll und der Compiler, während der Laufzeit, selbst den Programmablauf festlegt. Zudem gibt es in einem rein funktionalen Programm keine veränderbaren Variablen. 1.2 Motivation Aber warum verwendet man funktionale Programmiersprachen eigentlich? Weil diese viele Vorteile bieten, zum einen besitzen funktionale Programme einen sehr einfachen Aufbau, was dazu führt, dass diese Programme sehr schnell zu implementieren sind. Des Weiteren führt der einfache Aufbau, im Vergleich zur imperativen Programmierung, zu einem deutlich kürzeren Quellcode. Außerdem besitzen funktionale Programme den großen Vorteil der Seiteneffektfreiheit, welcher dazu führt, dass diese Programme eine sehr geringe Fehleranfälligkeit besitzen. Das alles führt dazu, dass funktionale Programme zum einen sehr einfach zu warten sind und zum anderen für Außenstehende, im Vergleich, deutlich leichter zu verstehen sind. 1.3 Aufbau Im zweiten Abschnitt befassen wir uns mit dem Konzept der Typklassen, welche ähnlich wie die Interfaces in Java, Typen in einer Klasse zusammenfassen, um das Arbeiten mit diesen Typen zu vereinfachen. Dabei beschäftigen wir uns mit den folgenden Fragen: Was sind Typklassen überhaupt? Welchen Zweck erfüllen sie? Wie genau funktionieren sie? Wie implementiert man sie? 1
2 In dem dritten Abschnitt beschäftigen wir uns mit dem Konzept der Monaden. Wir zeigen, was Monaden überhaupt sind, wie sie funktionieren und damit verbunden, wie sie das Programmieren erleichtern können und Programme so gestalten, dass man sie wieder leichter verändern kann. Am Ende dieses Abschnitts befassen wir uns mit einem Spezialfall der Monaden: Der I/O-Monade. Während dieses Abschnittes behandeln wir ebenfalls die Seiteneffektfreiheit, denn diese bietet, wie oben beschrieben, viele Vorteile. Jedoch ist die Seiteneffektfreiheit in der Praxis kaum umsetzbar, da Eingabe und Ausgabe gewünschte Seiteneffekte sind. Es stellt sich nun die Frage, wie diese Seiteneffektfreiheit in funktionalen Programmen weitgehend erhalten bleibt. 1.4 Haskell Da wir unter anderem einige Beispiele in Form von Quellcode darstellen werden, gehen wir in diesem Teil nochmal wichtige Konzepte der Programmiersprache Haskell durch. Syntax: Eine Typdeklaration wird in Haskell wie folgt dargestellt: Beispiel1.1: name :: type1 -> typeout Beispiel1.2: name :: type1 -> type2 ->... -> typeout In Beispiel1.1 ist name der Name der Funktion, type1 der Typ der Eingabe und typeout der Typ der Ausgabe. Wenn man mehrere Werte eingeben will, kann man das, wie in Beispiel1.2, mittels Currying machen. Dabei wird eine Folge von Argumenten Stück für Stück eingelesen, sodass es den Anschein erweckt, es sei eine Funktion mit mehreren Eingaben. Es gibt in Haskell eine vordefinierte Liste, welche man durch eckige Klammern kennzeichnet, jedoch werden wir im Folgenden eine selbstdefinierte Liste verwenden. Beispiel1.3: data List = LastElement Int RList Int List Der Datentyp List stellt hierbei unsere selbstdefinierte Liste dar. Die Liste soll nie leer sein, weshalb es immer zumindest ein LastElement, vom Typ Integer, gibt. Desweitern gibt es noch die RList, welche ebenfalls einen Integer enthält, jedoch auch eine weitere List. Somit ist dieser Datentyp sehr ähnlich zu einem Stack, in welchem ebenfalls immer das LIFO-Prinzip gültig ist. Mit diesem Wissen können wir nun eine Funktion definieren: Beispiel1.4: (1) restliste :: List -> List (2) restliste RList a b = b (3) restliste LastElement a = LastElement a Hier haben wir eine Funktion restliste, die ein Objekt von Typ List bekommt und ein Objekt vom Typ List ausgibt. Der Funktionskörper beschreibt nun, was die Funktion tun soll. Wie wir sehen, geben wir hier keine genaue Lösung vor, sondern definieren eine 2
3 Fallunterscheidung. Die Liste besteht entweder nur aus einem LastElement (3), oder aus einer RList mit einem Integer a und einer List b (2). Im Fall (2) wird die Liste, ohne ihr erstes Element, also nur b, und im Fall (3) wieder das LastElement a zurückgegeben. Der Compiler wertet dann die Eingabe aus und entscheidet, basierend auf der Eingabe, welcher der beiden Fälle (2) oder (3) ausgeführt wird. Ad-Hoc-Polymorphie: Der Begriff "Überladung" beschreibt die Möglichkeit mehrere Funktionen mit dem gleichen Namen zu benennen. Um nun entscheiden zu können, welche dieser Funktionen ausgeführt wird, wird das Prinzip der Ad-Hoc-Polymorphie verwendet. Um herauszufinden, welche Version der Funktion ausgeführt werden muss, verwendet der Compiler die Information darüber, mit welchem Typ die Funktion aufgerufen wurde. Es wird also "ad-hoc" entschieden, welche Funktion ausgeführt werden soll. Seiteneffektfreiheit: Seiteneffektfreiheit bedeutet unter anderem, dass übergebene Parameter nicht, im Verlauf einer Funktion, verändert werden können. Das führt dazu, dass die Reihenfolge von Funktionsaufrufen keine Rolle spielt, da für gleiche Eingabewerte auch immer die gleichen Ausgabewerte erzeugt werden. Wenn dieser Effekt noch gegeben ist, obwohl die Seiteneffektfreiheit verletzt wurde (zum Beispiel durch eine Eingabe), spricht man von referentieller Transparenz. Dies ist eine der Grundlagen der funktionalen Programmierung. Programme sind dadurch weniger fehleranfällig und weniger komplex. 2 Typklassen In diesem Kapitel befassen wir uns mit den Typklassen, welche ein Konstrukt der funktionalen Programmierung sind. Wir gehen darauf ein was Typklassen eigentlich sind und wir beschäftigen uns mit folgenden Fragen: "Wie funktionieren Typklassen?" und "Wie werden sie implementiert?" 2.1 Konzept Zuerst beschäftigen wir uns damit, was Typklassen sind und erläutern, warum Typklassen so wichtig und weit verbreitet sind. Die Idee hinter Typklassen ist vergleichbar mit der Funktion von Interfaces aus der objektorientierten Programmierung. Dort werden Interfaces dazu verwendet, die Gemeinsamkeiten verschiedener Klassen zusammenzufassen. Ähnlich dazu benutzt man in der funktionalen Programmierung Typklassen um Funktionen, die denselben Zweck erfüllen, für unterschiedliche Typen zusammenzufassen. Dafür wird das Prinzip der Ad-Hoc-Polymorphie verwendet, denn die Funktionen dieser Typklasse tragen für jeden Typen den gleichen Namen (Überladung) und der Compiler muss während der Laufzeit entscheiden, welche Funktion die Richtige ist. Typklassen erleichtern die Programmierarbeit, da der Programmierer sich keine Gedanken darüber machen muss, mit welchen Typen er eine Funktion aufruft. Mittlerweile sind Typklassen eines der wichtigsten Werkzeuge der funktionalen Programmierung. Aufgrund 3
4 dessen werden sie fast überall verwendet, häufig auch für die Definition von Schnittstellen (engl. Interfaces). 2.2 Aufbau Nun schauen wir uns den Aufbau von Typklassen an. Bei der Definition einer Typklasse werden die Namen der Funktionen, welche jeder Typ dieser Typklasse implementieren soll, festgelegt. Genauso wird die Art der Ein- und Ausgabetypen dieser Funktionen bestimmt und mögliche bereits bekannte Typen. Die festgelegten Namen und Typen werden dann für jede Implementierung dieser Funktionen verwendet. Typen dieser Typklasse werden durch einen Platzhalter dargestellt und erst bei der Implementierung durch den eigentlichen Typ ersetzt. Die Elemente einer Typklasse werden Instanzen genannt. Ihre Implementierung verläuft ähnlich zu der einer Unterklasse eines Interfaces, in der objektorientierten Programmierung. In jeder dieser Instanzen werden alle vorgegebenen Funktionen für einen bestimmten Typ (zum Beispiel Bool) implementiert. Ein Typ gehört zu einer Typklasse, falls es eine Instanz in dieser Typklasse gibt, welche alle Funktionen für diesen Typ enthält. 2.3 Implementierung Nachdem wir nun erfahren haben was Typklassen sind und wie sie funktionieren, zeigen wir jetzt anhand eines Beispiels wie man sie implementiert. Dabei werden die Vorteile dieses Konzepts nochmal besonders deutlich. Unser Beispiel ist die Typklasse Eq, welche auf Gleichheit und Ungleichheit prüft. Zu Beginn zeigen wir die Definition der Klasse: Beispiel2.1 (1) class Eq a where (2) (==),(/=) :: a -> a -> Bool Die Zeile (1) signalisiert, dass es sich um eine Klasse handelt und definiert a als Platzhalter für den Typ der Klasse Eq, welcher dann in den Instanzen, durch die Typen der Klasse, ersetzt wird. In Zeile (2) definieren wir nun die beiden Funktionen (==) und (/=) als Funktionen, die zweimal denselben Typen der Typklasse, als Eingabe erhalten und einen Wahrheitswert ausgeben. Als nächstes implementieren wir eine Instanz für die Typklasse Eq: (3) instance Eq Bool where (4) x == y = (x && y) (not x && not y) (5) x /= y = not ((x && y) (not x && not y)) In Zeile (3) wird definiert, dass es sich um die Instanz der Klasse Eq handelt und dass es in dieser Instanz um den Typen Bool geht. In Zeile (4) wird die Funktion (==) definiert, sodass nur True zurückgegeben wird, wenn entweder sowohl x, als auch y True sind, oder beide 4
5 False. In Zeile (5) wird die Funktion (/=), genauso wie die Funktion (==) definiert, nur dass die Ausgabe vorher noch negiert wird. Wie man sieht, kann man also (==) und (/=) als das Gegenteil des anderen definieren. Dafür gibt es für Typklassen eine schöne Lösung, die dem Programmierer Arbeit ersparen kann. Beispiel2.2 (1) class Eq a where (2) (==),(/=) :: a -> a -> Bool (3) x /= y = not (x == y) (4) x == y = not (x /= y) Nun haben wir in den Zeilen (3) und (4) die Abhängigkeit von (==) und (/=) schon in der Typklasse definiert, sodass wir in den Instanzen jeweils nur eins der beiden implementieren müssen. (5) instance Eq Bool where (6) x == y = (x && y) (not x && not y) (7) instance Eq Int where (8) x /= y = (x - y) < 0 (x - y) > 0 Durch die Kombination der Zeilen (6) und (3) ist nun sowohl (==) als auch (/=) für die Instanz definiert. Dasselbe gilt für die Instanz von Int und die Zeilen (8) und (4). Wie man sehen kann, erspart diese Technik dem Programmierer bei jeder neuen Instanz etwas Arbeit. Da wir nun dargestellt haben, wie man Typklassen implementiert, zeigen wir jetzt, wie man sie verwendet und einzelne Funktionen aufruft. So wird, zum Beispiel wenn man 3 == 4 aufruft, die Typklasse nach der Instanz von Int abgesucht. In dieser Instanz wird die Funktion (==) gesucht, welche in dieser Instanz als nicht (/=) definiert ist, sodass letzten Endes aus 3 == 4 die Abfrage not (3 /= 4) wird. Genauso könnten wir True == True aufrufen und der Compiler würde auch hierfür die passende Interpretation finden. Er würde nach der Instanz für Bool von Eq suchen und dort die definierte Funktion (==) verwenden. Wir sehen also, dass Typklassen ein starkes Werkzeug der funktionalen Programmierung sind, mit denen das Programmieren und verstehen des Codes vereinfacht wird. 5
6 3 Monaden Monaden sind ein sehr wichtiges Konzept der funktionalen Programmierung. Durch dieses Konzept können Programmteile gekapselt werden, sodass man Berechnungen getrennt voneinander ausführen kann, was auch dazu genutzt wird, um die Seiteneffekte zu kapseln. Desweitern lassen Programmeteile, sich durch Monaden, leichter abändern und wiederverwenden. Um dieses Thema zu erklären werden wir zuerst den Aufbau und Zweck von Monaden erläutern, dann, anhand von Beispielen, darstellen wie man mit ihnen programmiert und zuletzt den Spezialfall der I/O-Monade betrachten. 3.1 Einführung Im Verlauf dieses Abschnitts werden wir auf das Konzept, den Aufbau und die Gesetze von Monaden eingehen. Konzept: Monaden sind ein bedeutendes Werkzeug der funktionalen Programmierung und werden zur Behandlung von Fehlern und Ausnahmen und zur Ein- und Ausgabe verwendet. Außerdem helfen sie dabei, dass Programme in Module unterteilt werden und dadurch wesentlich einfacher wiederzuverwerten und zu verändern sind. Diese Vorteile werden durch das Prinzip der Kapselung erreicht. Eine Monade kapselt Aufgaben eines Programms und führt diese unabhängig von der Umgebung aus. So werden zum Beispiel Berechnungen in einer Funktion voneinander getrennt, sodass man bei Änderungswunsch nur die Monadendefinition, aber nicht das komplette Programm, umschreiben muss. Dadurch wird das Programm deutlich lesbarer und ist einfacher zu warten. Denn das Programm wird, durch die Kapselung, in Module unterteilt. Dies kann auch dazu benutzt werden, um Seiteneffekte in Monaden zu kapseln und so die referentielle Transparenz im Rest des Programms zu gewährleisten. Monaden gehören zu den Konstruktorklassen, um also verstehen zu können was genau eine Monade ist, muss man zuerst verstanden haben was Konstruktorklassen sind. Konstruktorklassen: Konstruktorklassen sehen den Typklassen sehr ähnlich. Der wichtige Unterschied hierbei ist, dass Typklassen dazu verwendet werden, Funktionen für unterschiedliche Typen zusammenzufassen. Konstruktorklassen hingegen werden dazu verwendet, Funktionen für unterschiedliche Konstruktoren zu sammeln. Konstruktoren können zum Beispiel Funktionen der Form * -> * sein, wobei * entweder ein Typ oder ein weiterer Konstruktor ist. Sie können auch als erweiterte Typklassen bezeichnet werden, da sie die Aufgabe der Typklassen auch auf Konstruktoren ausweiten. Aufbau und Implementierung: Nun befassen wir uns mit dem Aufbau einer Monade, dazu schauen wir uns einen Auszug der Definition der Konstruktorklasse Monad an. 6
7 Beispiel3.1 (1) class Monad m where (2) return :: a -> m a (3) (>>=) :: m a -> (a -> m b) -> m b Der Aufbau ist prinzipiell sehr ähnlich zu dem Aufbau einer Typklasse. Der Unterschied hierbei ist, dass m hier kein Platzhalter für einen Typ, sondern für einen Konstruktor ist. a und b sind gewöhnliche Typen. Der Rest ist identisch zu den Typklassen, also Zeile (1) ist die Kopfzeile und in den Zeilen (2) und (3) werden die Funktionen, welche in jeder Monade enthalten seien müssen, definiert. Die Funktion in Zeile (2) ist die return"-funktion. Diese dient dazu, Werte oder Aktionen in der Monade zu kapseln. Das wird dadurch deutlich, dass in dem Code aus dem a ein m a gemacht wird. Mit anderen Worten: Der Aufruf return a kapselt a in eine Monade m. Einen solchen gekapselten Wert werden wir im Folgenden so darstellen: Es gibt noch weitere Funktion, welche oben nicht definiert sind, eine davon ist der then- Operator, welcher wie folgt definiert ist: (>>) :: m a -> m b -> m b Dieser wird dazu verwendet, um mehrere Aufrufe hintereinander auszuführen. Das Problem beim then-operator ist, dass wir das Ergebnis von m a verlieren, sobald wir m b ausführen, da das Ergebnis nicht weitergegeben wird. Dadurch ist der then-operator nur nützlich, wenn uns das Ergebnis egal ist und sieht wie folgt aus: Also benutzen wir den bind"-operator, mit dem man sozusagen einen Wert übergeben kann und welcher in Zeile 3 definiert ist. Das funktioniert so, indem m a ausgeführt und das Ergebnis genommen wird. Darauf wird dann "m b" ausgeführt und als Ergebnis erhält man dann einen Wert vom Typ m b. Das sieht dann so aus: Das Schema, der Erzeugung von neuen Instanzen, ist dasselbe wie bei den Typklassen. Die Monaden sind die Elemente, also die Instanzen, der Konstruktorklasse Monad. Die Instanzendeklaration ist genau gleich, wie bei den Typklassen. Man startet also mit der Zeile: instance Monad name where Anschließend müssen die Funktionen "return" und "bind" für die Monade individuell implementiert werden. Monadengesetze: Für die Definition der Funktionen einer Monade gibt es drei Gesetze. Diese beschreiben einige Regeln, wie sich die Funktionen verhalten sollen. Der Compiler kann nicht 7
8 überprüfen, ob die Gesetze erfüllt sind oder nicht, jedoch spricht man erst von einer Monade, wenn alle drei Gesetze gelten. Daher sollte jeder gute Code diesen Gesetzen entsprechen. 1. p >>= return = p Wenn man zuerst eine Aktion p ausführt und daraufhin die Aktion return verwendet, erhält man dasselbe Ergebnis, wie wenn man nur die Aktion p aufruft. Die erste Regel besagt also, dass return das rechtsneutrale Element zu >>= ist. 2. return x >>= f = f x Es wird zuerst die Aktion return, mit einer beliebigen Eingabe x, aufgerufen und auf das Ergebnis eine Aktion f verwendet, welche das gekapselte Element x benutzt, sodass das gleiche heraus kommt, als würde man einfach nur f x ausführen. Also sagt die zweite Regel aus, dass return ebenfalls das linksneutrale Element zu >>= ist. Regel 1 und 2 stellen in Kombination sicher, dass return sowohl linksneutral als auch rechtsneutral, zu der bind-funktion, ist und somit die "leere Aktion" implementiert. 3. (p >>= \x -> q) >>= r = p >>= \x -> (q >>= r) falls x nicht in r auftritt. Auf der linken Seite führen wir zuerst die Aktion p und daraufhin die Aktion q, mit dem Ergebnis von p, aus. Zuletzt wird die Aktion r, mit dem Ergebnis von q, durchgeführt. Auf der rechten Seite werden stattdessen die Aktionen q und r gebündelt und darauf dann das Ergebnis von p aufgerufen. Da laut Gesetz beide Seiten das Identische bewirken, kann man schlussfolgern, dass das dritte Gesetz die Asoziativität von >>= beschreibt. Mit anderen Worten, wir können Klammern setzen, ohne damit eine Veränderung des Ergebnisses zu bewirken. 3.2 Implementierung (Beispiel) In diesem Kapitel werden wir uns damit beschäftigen, wie man mit Monaden programmiert und welche Vorteile das hat. Dies werden wir anhand eines Beispiels, in welchem wir einmal keine Monade verwenden und dann zum Vergleich die Maybe Monade benutzen, erläutern. Wir wollen nun eine Funktion f implementieren, die eine selbstdefinierte Liste von Integern erhält und die Summe ihrer Elemente bestimmt. Allerdings soll die Einschränkung gelten, dass die Liste keine ungeraden Zahlen enthält. Sollte die Liste dennoch welche enthalten, so soll Nothing zurückgegeben werden. Dafür erstellen wir zunächst zwei eigene Datentypen: data Maybe a = Just a Nothing data List = LastElement Int RList Int List Hierbei beschreibt Maybe die Art unserer Ausgabe. Erlaubte Werte, als gerade Integer Zahlen, sollen als Just x bezeichnet werden, wobei x genau dieser Wert ist. Nothing wird verwendet, wenn ein ungerader Integer, in der Liste, enthalten ist und stellt somit eine Art 8
9 Fehlerausgabe dar. Der Datentyp List ist hierbei derselbe wie der, den wir in Kapitel 1 eingeführt haben. Nun definieren wir unsere Funktion f: f :: List -> Maybe Int f (LastElement x) (mod x 2) == 0 = Just x otherwise = Nothing f (RList x y) = case f y of Nothing -> Nothing Just y -> case (mod x 2) of 0 -> Just (x + y) 1 -> Nothing Die Funktion f bekommt als Eingabe ein Objekt List und gibt einen Maybe Int Wert zurück. Bei der Eingabe müssen wir nun in zwei Fälle unterscheiden: Im ersten Fall ist die Eingabe ein LastElement x. Es muss hierbei vorerst überprüft werden, ob x ein gerader oder ungerader Integer Wert ist. Dies wird mittels einer Fallunterscheidung umgesetzt. Sollte (mod x 2) gleich 0 sein, also x ist ein gerader Integer und somit ein gültiger Wert, wird Just x zurückgegeben. Sollte das nicht zutreffen, also x ist ungerade und somit ein ungültiger Wert, wird Nothing zurückgegeben. Im zweiten Fall erhält die Funktion f eine RList. Zuerst wird die Funktion f rekursiv auf die restliche Liste y (vom Typ List) angewendet. Sollte Nothing zurückgegeben werden, was bedeutet, dass die Liste y einen ungültigen Wert enthält, so gibt auch die Funktion f wieder Nothing zurück. Wenn jedoch Just a zurückgegeben wird, wobei a ein Integer ist, welcher die Summe aller Elemente von y darstellt, so wird nun mit der Modulo Funktion überprüft, ob der Wert von x gerade ist. Sollte dies so sein, bedeutet das, dass weder x ungültig ist, noch dass y einen ungültigen Wert enthält. Dann wird als Ergebnis Just mit der Summe von x und a zurückgegeben. Sollte x jedoch ungerade und somit ungültig sein, wird einfach Nothing zurückgegeben. Nun zeigen wir, wie das Ganze mit einer Monade implementiert wird und werden hierbei die Vorteile einer Monade nochmals erläutern. Dazu erklären wir zuerst die Definition der Maybe Monade: instance Monad Maybe where return x = Just x Nothing >>= q = Nothing Just x >>= q = q x Diese Monade ist eine Instanz der Konstruktorklasse Monad und trägt den Namen Maybe. Es ist eine der am häufigsten verwendeten Monaden die es gibt, da sie dem Programmierer erlaubt, etwas auszudrücken, was vielleicht gar nicht vorhanden ist. Die return Funktion, gibt auf jede Eingabe x, Just x zurück. Für die bind Funktion muss man zwischen zwei Fällen unterscheiden: Der erste Fall besagt, dass wenn man Nothing, mit einer anderen Funktion, verknüpfen will, kommt wieder Nothing heraus. Im zweiten Fall 9
10 wird Just x mit einer beliebigen Funktion q verknüpft und die Ausgabe ist das Ergebnis, der Funktion q, wenn man sie auf x anwendet. Jetzt schreiben wir unsere Funktion f mit der Hilfe der Monade um. Diese neue Funktion nennen wir fm und sieht wie folgt aus: fm :: List -> Maybe Int fm (LastElement x) (mod x 2) == 0 = return x otherwise = Nothing fm (RList x y) = do a <- fm y if (mod x 2) == 0 then return (a + x) else Nothing Der Grundaufbau der Funktion fm ist derselbe, wie der unserer Funktion f. Wir bekommen hier auch ein Objekt List, als Eingabe der Funktion, und geben ebenfalls einen Maybe Int Wert zurück. Wir haben auch, in der Funktion fm, wieder die Fallunterscheidung für die Eingaben LastElement x und RList x y. Der erste Fall wird fast gleich implementiert, wie in der Funktion f. Der einzige Unterschied besteht darin, dass wir die Monade, bei der Ausgabe, verwenden, also statt Just x geben wir return x aus. Im zweiten Teil, der Funktion, wird deutlich mehr verändert. Hierbei verwenden wir die do-notation, welche eine spezielle Notation für Verknüpfungen von "bind"-operatoren ist. Dies ist also keine neue Funktion, sondern vereinfacht nur die Schreibweise und macht den Code verständlicher. Die alternative Form, für die do-notation unseres Beispiels, sähe so aus: fm (RList x y) = fm y >>= \a -> if ((mod x 2) == 0) then return (a + x) else Nothing Wir führen also zuerst die Funktion fm auf y aus und setzen a auf den darin gekapselten Wert. Dann wird mittels einer if-abfrage überprüft, ob x ein gültiger Werte ist, also ob x ein gerader Integer Wert ist. Wenn dies der Fall ist wird das Ergebnis, also die Summe von a und x, mittels der return-funktion in der Monade gekapselt, zurückgegeben. Ansonsten wird Nothing als Monaden-Objekt ausgegeben. Wir haben nun eine Funktion auf zwei verschiedene Arten definiert. Einmal komplett ohne den Einsatz von Monaden und einmal mit Benutzung der Maybe Monade. Im Vergleich stellt sich nun die Frage, wieso man überhaupt Monaden verwendet, da das Beispiel mit Monade nicht wesentlich kürzer erscheint und mit der Definition der Monade sogar noch länger ist. Jedoch muss man beachten, dass wir hier lediglich eine Funktion implementiert haben und man auf diese Art und Weise natürlich viele Funktion implementieren kann, ohne dafür eine neue Monade definieren zu müssen. Außerdem wird der Code dadurch deutlich verständlicher, da man die case-verschachtelung umgeht. Des Weiteren können wir nun, durch die Modularität, welche durch die Monade zustande kommt, die Programme sehr viel einfacher anpassen, da man nur noch die einzelnen Module, also die Monaden, verändern muss und nicht jede einzelne Funktion. Wenn man all diese Aspekte betrachtet, kann man nun feststellen, dass es doch sehr sinnvoll ist, mit Monaden zu arbeiten und dass sich das in der Praxis sehr lohnen kann. 10
11 3.3 I/O-Monade Zu Beginn haben wir uns die Frage gestellt, wie man mit Seiteneffekten, in der funktionalen Programmierung umgeht. Auch hier kommt uns das Konzept der Monade zu Hilfe und zwar in Form der I/O-Monade, welche ein Spezialfall der Konstruktorklasse Monad ist. Die I/O-Monade ist eine der wichtigsten und meist verwendeten Monaden, da sie für die Eingabe und Ausgabe zuständig ist. Das Besondere bei der I/O-Monade ist, dass sie keine Werte speichert, sondern Aktionen. Das heißt, Werte werden in diesen Aktionen gekapselt. Genauer erkennt man das an folgendem Beispiel: getchar :: IO Char Die Funktion getchar wird dazu benutzt, um Tastatureingaben einzulesen. Allerdings speichert IO keine Werte, also auch keine Tastatureingaben. In diesem Fall wird sozusagen die Aktion "lese ein" gespeichert. Das führt dazu, dass man keine Werte aus einer I/O- Monade extrahieren kann. Dies ist sehr wichtig, da die Werte, mit denen IO arbeitet, Seiteneffekt behaftet sind. Würde man diese Werte extrahieren können, hätte man die Seiteneffekte in seinem Programm und die referentielle Transparenz wäre verletzt. Eine weitere Funktion, die auf der I/O-Monade beruht ist putchar: putchar:: Char -> IO () Die Funktion putchar dient zur Ausgabe und gibt ein Zeichen aus. Auch hier ist zu erkennen, dass lediglich eine IO Aktion und kein fester Wert gespeichert wird. Um nochmal zu verdeutlichen, wie wichtig dies ist, nehmen wir folgendes Beispiel: getchar >>= putchar Hier lesen wir zuerst eine Tastatureingabe ein und geben diese anschließend aus. Durch die Eingabe bekommen wir Seiteneffekte. Unsere, durch "bind" verknüpfte, Funktionen beschreiben nun die Aktionen "lese Wert ein und gebe ihn aus". Der Wert bleibt dabei dauerhaft gekapselt und hat keinen Einfluss auf unser übriges Programm. Die referentielle Transparenz unseres Programms ist also weiterhin gegeben. Würden wir diese Seiteneffekte in unser Programm lassen, müssten wir unter anderem darauf achten, in welcher Reihenfolge wir Funktionen aufrufen, da wir nicht immer das gleiche Ergebnis erwarten können. Dies würde auch das Programmieren erschweren und die in der Einleitung genannten Vorteile zunichtemachen. Wie wir sehen können, hilft uns die I/O- Monade dabei unsere Programme, auch bei Ein- und Ausgabe, weitgehend Seiteneffektfrei zu halten. 11
12 4 Zusammenfassung Wir haben jetzt einige der wichtigsten Konzepte der funktionalen Programmierung kennen gelernt. Nachdem wir uns mit den Vorteilen und Besonderheiten der funktionalen Programmierung beschäftigten, haben wir uns mit dem Konzept der Typklassen befasst. Dies ist ein sehr wichtiges Konzept, da es ermöglicht Funktionen für viele verschiedene Typen unter demselben Namen zu implementieren und zusammenzufassen. Dieses Konzept trägt dadurch nicht nur zur Lesbarkeit bei, sondern verringert auch die Fehleranfälligkeit und sorgt dafür, dass Funktionen wesentlich einfacher und schneller zu implementieren sind. Anschließend haben wir uns dem großen Thema Monaden gewidmet. Wir haben gezeigt, dass sie das Programmieren auf unterschiedlichen Ebenen erleichtern. Zum einen sorgen sie dafür, dass die Modularität des Programms gesteigert wird, was dazu führt, dass man einzelne Teile des Programms leichter verändern kann. Zum anderen wird der Code dadurch deutlich lesbarer und ist für Außenstehende einfacher zu verstehen. Außerdem wird mithilfe der I/O-Monade die referentielle Transparenz, durch die Kapselung von Werten in Aktionen, bewahrt und stellt damit einen wichtigen Aspekt der funktionalen Programmierung sicher. Abschließend bleibt zu sagen, dass funktionale Programmiersprachen sich zwar deutlich von imperativen Sprachen unterscheiden und man sich erstmal an diese Sprachen gewöhnen muss, bevor man effizient mit ihnen arbeiten kann. Jedoch bringen sie viele Vorteile mit sich, durch die das Programmieren vereinfacht wird. Man kann also sagen, dass es sich oft durchaus lohnt auf funktionale Programmiersprachen zurückzugreifen. Quellen - Skript zur Vorlesung: Funktionale Programmierung, SS 2016, Jürgen Giesl, - Tackling the Awkward Squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell, Simon Peyton Jones, - Real World Haskell by Bryan O'Sullivan, Don Stewart, and John Goerzen, 2010, O'Reilly 12
Gliederung. n Teil I: Einleitung und Grundbegriffe. n Teil II: Imperative und objektorientierte Programmierung
Gliederung n Teil I: Einleitung und Grundbegriffe l 1. Organisatorisches l 2. Grundlagen von Programmiersprachen n Teil II: Imperative und objektorientierte Programmierung l 1. Grundelemente der Programmierung
MehrHaskell for Hackers... or why functional programming matters
... or why functional programming matters Franz Pletz CCC München 27-06-2009 @ GPN8 Fahrplan Ablauf Motivation 1 Ablauf Motivation 2 3 4 Ablauf Ablauf Motivation bei Fragen/Unklarheiten:
MehrFunktionale Programmierung
Monaden LFE Theoretische Informatik, Institut für Informatik, Ludwig-Maximilians Universität, München 30. April 2009 Monaden Eine Monade ist ein Programmier-Schema für sequentielle Berechnungen. In Haskell
MehrPraktische Informatik 3
Praktische Informatik 3 Christian Maeder WS 03/04 Vorlesung vom 12.1.2004: Ein/Ausgabe in funktionalen Sprachen Vorlesung vom 12.1.2004: Ein/Ausgabe in funktionalen Sprachen 3 Inhalt Wo ist das Problem?
MehrProinformatik Marco Block Dienstag, den 21. Juli 2009
2. Skript vom Dienstag, den 21. Juli 2009 zur Vorlesung Proinformatik Marco Block Dienstag, den 21. Juli 2009 1 Verschiedenes 1.1 let und where Am Anfang der Vorlesung haben wir uns ein paar einfache neue
MehrGrundlegende Datentypen
Grundlegende Datentypen Funktionale Programmierung Prof. Dr. Oliver Braun Letzte Änderung: 22.10.2018 10:53 Grundlegende Datentypen 1/21 Typen in Haskell ist alles streng typisiert Haskell verfügt über
MehrProgrammieren in Haskell Einstieg in Haskell
Programmieren in Haskell Einstieg in Haskell Peter Steffen Universität Bielefeld Technische Fakultät 24.10.2008 1 Programmieren in Haskell Was wir heute machen Umfrage: Wer hat den Hugs ausprobiert? Ausdrücke
MehrIII.1 Prinzipien der funktionalen Programmierung - 1 -
1. Prinzipien der funktionalen Programmierung 2. Deklarationen 3. Ausdrücke 4. Muster (Patterns) 5. Typen und Datenstrukturen 6. Funktionale Programmiertechniken III.1 Prinzipien der funktionalen Programmierung
MehrProgrammieren in Haskell
Programmieren in Haskell Wir steigen ein... Programmieren in Haskell 1 Was wir heute machen Umfrage: Wer hat den Hugs ausprobiert? Ausdrücke und Werte Datentypen Funktionen Aufgabe für diese Woche Programmieren
MehrFunktionen in JavaScript
Funktionen in JavaScript Eine Funktion enthält gebündelten Code, der sich in dieser Form wiederverwenden lässt. Mithilfe von Funktionen kann man denselben Code von mehreren Stellen des Programms aus aufrufen.
MehrFunktionen in JavaScript
Funktionen in JavaScript Eine Funktion enthält gebündelten Code, der sich in dieser Form wiederverwenden lässt. Es können ganze Programmteile aufgenommen werden. Mithilfe von Funktionen kann man denselben
MehrIntensivübung zu Algorithmen und Datenstrukturen
Intensivübung zu Algorithmen und Datenstrukturen Silvia Schreier Informatik 2 Programmiersysteme Martensstraße 3 91058 Erlangen Übersicht Programmierung Fallunterscheidung Flussdiagramm Bedingungen Boolesche
Mehr41.8 LUA-Grundlagen - Tabelle, if und Albernheit
41.8 LUA-Grundlagen - Tabelle, if und Albernheit Autor: Goetz Quelle: Mein EEP-Forum In diesem Kapitel möchte ich eine erste, einfache Anwung von Lua auf einer Anlage zeigen. Ich werde mich dabei auf den
MehrParadigmen der Programmierung
SS 11 Prüfungsklausur 25.07.2011 Aufgabe 5 (6+9 = 15 Punkte) a) Bestimmen Sie jeweils den Typ der folgenden Haskell-Ausdrücke: ( 1, 2 :"3", 4 < 5) :: (Char, String, Bool) [(last, tail), (head, take 5)]
Mehrpue13 January 28, 2017
pue13 January 28, 2017 1 Aufgabe 1 (Klammern und Anweisungsblöcke) Wie Sie in der Vorlesung gelernt haben, werden Anweisungsblöcke in Java nicht durch Einrückung, sondern mithilfe von geschweiften Klammern
MehrObjektorientierte Programmierung. Kapitel 22: Aufzählungstypen (Enumeration Types)
Stefan Brass: OOP (Java), 22. Aufzählungstypen 1/20 Objektorientierte Programmierung Kapitel 22: Aufzählungstypen (Enumeration Types) Stefan Brass Martin-Luther-Universität Halle-Wittenberg Wintersemester
MehrALP I. Funktionale Programmierung
ALP I Funktionale Programmierung Typ-Klassen und SS 2011 Überladung von Datentypen Funktionen sollen oft auf verschiedene Datentypen anwendbar sein, aber nicht auf beliebige Datentypen. Beispiel: Die (+)
MehrInformatik-Seminar Thema: Monaden (Kapitel 10)
Informatik-Seminar 2003 - Thema: Monaden (Kapitel 10) Stefan Neumann 2. Dezember 2003 Inhalt Einleitung Einleitung Die IO()-Notation Operationen Einleitung Gegeben seien folgende Funktionen: inputint ::
MehrEinführung in Haskell
Einführung in Haskell Axel Stronzik 21. April 2008 1 / 43 Inhaltsverzeichnis 1 Allgemeines 2 / 43 Inhaltsverzeichnis 1 Allgemeines 2 Funktions- und Typdefinitionen 2 / 43 Inhaltsverzeichnis 1 Allgemeines
MehrProgrammieren in Haskell
Programmieren in Haskell Wir steigen ein... Programmieren in Haskell 1 Was wir heute machen Umfrage: Wer hat den Hugs ausprobiert? Ausdrücke und Werte Datentypen Funktionen Aufgabe für s Wochenende Programmieren
MehrErste Java-Programme (Scopes und Rekursion)
Lehrstuhl Bioinformatik Konstantin Pelz Erste Java-Programme (Scopes und Rekursion) Tutorium Bioinformatik (WS 18/19) Konstantin: Konstantin.pelz@campus.lmu.de Homepage: https://bioinformatik-muenchen.com/studium/propaedeutikumprogrammierung-in-der-bioinformatik/
MehrAngewandte Mathematik und Programmierung
Angewandte Mathematik und Programmierung Einführung in das Konzept der objektorientierten Anwendungen zu mathematischen Rechnens WS 2013/14 Operatoren Operatoren führen Aktionen mit Operanden aus. Der
MehrPrüfung Funktionale Programmierung
Hochschule für angewandte Wissenschaften München Fakultät für Informatik und Mathematik Studiengruppe IF, IB, IC Sommersemester 2015 Prüfung Funktionale Programmierung Datum : 23.07.2015, 10:30 Uhr Bearbeitungszeit
MehrObjektorientierte Programmierung mit C++ (WS 2016/2017)
Institut für Numerische Mathematik Dr. Andreas F. Borchert und Dr. Michael C. Lehn 26. Januar 2017 Blatt 12 Objektorientierte Programmierung mit C++ (WS 2016/2017) Abgabe bis zum 2. Februar 2017, 16:00
MehrPROCESSING EINE ZUSAMMENFASSUNG. Created by Michael Kirsch & Beat Rossmy
PROCESSING EINE ZUSAMMENFASSUNG Created by Michael Kirsch & Beat Rossmy INHALT 1. Typen und Operatoren 1. Datentypen 3. Klassen und Objekte 1. Klassen und Objekte 2. Operatoren 2. Konstruktor 3. Typkonversion
MehrDas diesem Dokument zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung und Forschung unter dem Förderkennzeichen
Das diesem Dokument zugrundeliegende Vorhaben wurde mit Mitteln des Bundesministeriums für Bildung und Forschung unter dem Förderkennzeichen 16OH21005 gefördert. Die Verantwortung für den Inhalt dieser
MehrObjektorientierung. Marc Satkowski 20. November C# Kurs
Objektorientierung Marc Satkowski 20. November 2016 C# Kurs Gliederung 1. Weiterführende Verzweigungen Tertiäre-Verzweigung switch case 2. Schleifen Zählschleife (for) break & continue 3. Objektorientierung
MehrBasiskonstrukte von Haskell
Basiskonstrukte von Haskell PD Dr. David Sabel Goethe-Universität Frankfurt am Main 29. September 2015 Basistypen und Operationen Ganzzahlen: Int = Ganzzahlen beschränkter Länge Integer = Ganzzahlen beliebiger
MehrVorlesung Programmieren
Vorlesung Programmieren Programmierparadigmen Prof. Dr. Stefan Fischer Institut für Telematik, Universität zu Lübeck http://www.itm.uni-luebeck.de/people/fischer Programmiersprachen-Paradigmen Eine Programmiersprache
MehrVorlesung Programmieren. Programmiersprachen-Paradigmen. Programmierparadigmen. Eine Programmiersprache dient dem Aufschreiben von Algorithmen
Vorlesung Programmieren Programmierparadigmen Prof. Dr. Stefan Fischer Institut für Telematik, Universität zu Lübeck http://www.itm.uni-luebeck.de/people/fischer Programmiersprachen-Paradigmen Eine Programmiersprache
MehrProbeklausur: Programmierung WS04/05
Probeklausur: Programmierung WS04/05 Name: Hinweise zur Bearbeitung Nimm Dir für diese Klausur ausreichend Zeit, und sorge dafür, dass Du nicht gestört wirst. Die Klausur ist für 90 Minuten angesetzt,
MehrJavaScript. Dies ist normales HTML. Hallo Welt! Dies ist JavaScript. Wieder normales HTML.
JavaScript JavaScript wird direkt in HTML-Dokumente eingebunden. Gib folgende Zeilen mit einem Texteditor (Notepad) ein: (Falls der Editor nicht gefunden wird, öffne im Browser eine Datei mit der Endung
Mehr1 Bedingte Anweisungen. 2 Vergleiche und logische Operatoren. 3 Fallunterscheidungen. 4 Zeichen und Zeichenketten. 5 Schleifen.
Themen der Übung Kontrollstrukturen, Pseudocode und Modulo-Rechnung CoMa-Übung III TU Berlin 9.10.01 1 Bedingte Anweisungen Vergleiche und logische Operatoren 3 Fallunterscheidungen 4 Zeichen und Zeichenketten
MehrKlausur Grundlagen der Programmierung
Klausur Grundlagen der Programmierung Aufgabenstellung: Martin Schultheiß Erreichte Punktzahl: von 60 Note: Allgemeine Hinweise: Schreiben Sie bitte Ihren Namen auf jedes der Blätter Zugelassene Hilfsmittel
MehrFunktionale Programmiersprachen
Funktionale Programmiersprachen An den Beispielen Haskell und Erlang Übersicht Programmiersprachen λ-kalkül Syntax, Definitionen Besonderheiten von funktionalen Programmiersprache, bzw. Haskell Objektorientierte
MehrProgrammieren Vorkurs
Programmieren Vorkurs Input/Output, If, Bedingungen Thole Goesmann, 10.10.2018 Über mich Thole Goesmann Studiere Mathematik und Informatik HiWi am Institut für Anwendungssicherheit gewähltes Mitglied im
MehrTyp-Polymorphismus. November 12, 2014
Typ-Polymorphismus Universität Bielefeld AG Praktische Informatik November 12, 2014 Das Haskell Typ-System Wir beginnen mit einer Wiederholung des Bekannten: In allen Programmiersprachen sind Typ-Konzepte
MehrFunktionale Programmierung Mehr funktionale Muster
Mehr funktionale Muster Prof. Dr. Oliver Braun Fakultät für Informatik und Mathematik Hochschule München Letzte Änderung: 07.12.2017 06:56 Inhaltsverzeichnis Pattern Matching..................................
MehrJava 8. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Oktober 2014 JAV8
Java 8 Elmar Fuchs Grundlagen Programmierung 1. Ausgabe, Oktober 2014 JAV8 5 Java 8 - Grundlagen Programmierung 5 Kontrollstrukturen In diesem Kapitel erfahren Sie wie Sie die Ausführung von von Bedingungen
MehrJava Methoden. Informatik 1 für Nebenfachstudierende Grundmodul. Kai-Steffen Hielscher Folienversion: 1. Februar 2017
Informatik 1 für Nebenfachstudierende Grundmodul Java Methoden Kai-Steffen Hielscher Folienversion: 1. Februar 2017 Informatik 7 Rechnernetze und Kommunikationssysteme Inhaltsübersicht Kapitel 3 - Java
MehrPrüfung Funktionale Programmierung
Hochschule für angewandte Wissenschaften München Fakultät für Informatik und Mathematik Studiengruppe IF, IB, IC Sommersemester 2014 Prüfung Funktionale Programmierung Datum : 16.07.2014, 12:30 Uhr Bearbeitungszeit
MehrAlgorithmen und Programmieren 1 Funktionale Programmierung - Musterlösung zur Übungsklausur -
Algorithmen und Programmieren 1 Funktionale Programmierung - Musterlösung zur Übungsklausur - Punkte: A1: 30, A2: 20, A3: 20, A4: 20, A5: 10, A6: 20 Punkte: /120 12.02.2012 Hinweis: Geben Sie bei allen
MehrKlausur: Grundlagen der Informatik I, am 06. Februar 2009 Gruppe: A Dirk Seeber, h_da, Fb Informatik. Nachname: Vorname: Matr.-Nr.
Seite 1 von 9 Hiermit bestätige ich, dass ich die Übungsleistungen als Voraussetzung für diese Klausur in folgender Übung erfüllt habe. Jahr: Übungsleiter: Unterschrift: 1. Aufgabe ( / 12 Pkt.) Was liefert
MehrPraktische Informatik 3: Funktionale Programmierung Vorlesung 4 vom : Typvariablen und Polymorphie
Rev. 2749 1 [28] Praktische Informatik 3: Funktionale Programmierung Vorlesung 4 vom 04.11.2014: Typvariablen und Polymorphie Christoph Lüth Universität Bremen Wintersemester 2014/15 2 [28] Fahrplan Teil
Mehr2. Programmierung in C
2. Programmierung in C Inhalt: Überblick über Programmiersprachen, Allgemeines zur Sprache C C: Basisdatentypen, Variablen, Konstanten Operatoren, Ausdrücke und Anweisungen Kontrollstrukturen (Steuerfluss)
MehrC.3 Funktionen und Prozeduren
C3 - Funktionen und Prozeduren Funktionsdeklarationen in Pascal auch in Pascal kann man selbstdefinierte Funktionen einführen: Funktionen und Prozeduren THEN sign:= 0 Funktion zur Bestimmung des Vorzeichens
MehrC++ - Objektorientierte Programmierung Konstruktoren und Destruktoren
C++ - Objektorientierte Programmierung Konstruktoren und Destruktoren hat eine Kantenlänge hat eine Füllfarbe Kantenlänge setzen Füllfarbe lesen Volumen berechnen Leibniz Universität IT Services Anja Aue
Mehr41.2 LUA Grundlagen - Funktionen
41.2 LUA Grundlagen - Funktionen Autor: Goetz Quelle: Mein EEP-Forum Im Grunde genommen sind Funktionen - Programmierer schauen jetzt bitte mal weg! - auch Variablen. Jedenfalls gibt es da einige Gemeinsamkeiten.
MehrÜbung zur Vorlesung Wissenschaftliches Rechnen Sommersemester 2012 Auffrischung zur Programmierung in C++, 1. Teil
MÜNSTER Übung zur Vorlesung Wissenschaftliches Rechnen Sommersemester 2012 Auffrischung zur Programmierung in C++ 1. Teil 11. April 2012 Organisatorisches MÜNSTER Übung zur Vorlesung Wissenschaftliches
Mehr4.4 Imperative Algorithmen Prozeduren
4.4.2 Prozeduren Der Wert eines Ausdrucks u in Zustand z Z lässt sich damit auch leicht definieren (jetzt W Z statt W σ ) Dazu erweitern wir die rekursive Definition von Folie 57 (Wert eines Ausdrucks):
MehrTag 3. Funktionen. Num erfüllen, haben wir... ja, was nun eigentlich? Bei
Tag 3 Funktionen Heute werden wir den wichtigsten Typ (oder die wichtigste Klasse von Typen) in Haskell überhaupt genau unter die Lupe nehmen: Funktionen, die wir ansatzweise schon am letzten Tag kennengelernt
MehrÜbung zur Vorlesung Wissenschaftliches Rechnen Sommersemester 2012 Auffrischung zur Programmierung in C++, 1. Teil
MÜNSTER Übung zur Vorlesung Wissenschaftliches Rechnen Sommersemester 2012 Auffrischung zur Programmierung in C++ 1. Teil 11. April 2012 Organisatorisches MÜNSTER Übung zur Vorlesung Wissenschaftliches
MehrKonzepte der Programmiersprachen
Konzepte der Programmiersprachen Sommersemester 2010 4. Übungsblatt Besprechung am 9. Juli 2010 http://www.iste.uni-stuttgart.de/ps/lehre/ss2010/v_konzepte/ Aufgabe 4.1: Klassen in C ++ Das folgende C
MehrProgrammieren in Haskell
Programmieren in Haskell Monaden Programmieren in Haskell 1 Sequenzierung mit Dollar und Euro Die Atommüll-Metapher Maybe- und Listen-Monaden Return Die do-notation Monaden als Berechnungen Listenbeschreibungen
MehrProgrammierpraktikum
TECHNISCHE UNIVERSITÄT MÜNCHEN FAKULTÄT FÜR INFORMATIK Praktikum: Grundlagen der Programmierung Programmierpraktikum Woche 04 (17.11.2016) Stefan Berktold s.berktold@tum.de PRÄSENZAUFGABEN Heutige Übersicht
MehrSichtbarkeiten, Klassenmember und -methoden
Sichtbarkeiten, Klassenmember und -methoden Prof. Dr.-Ing. Thomas Schwotzer 11. November 2017 1 Einführung Wir haben uns mit Klassen und Objekten beschäftigt. Wir wissen nun, dass Objekte anhand von Klassen
MehrBeuth Hochschule Parameter-Übergabe-Mechanismen WS17/18, S. 1
Beuth Hochschule Parameter-Übergabe-Mechanismen WS17/18, S. 1 Parameter-Übergabe-Mechanismen in Java und in anderen Sprachen. 1. Methoden vereinbaren mit Parametern Wenn man (z.b. in Java) eine Methode
MehrObjektorientiertes Programmieren (Java)
Grundlagen Objektorientiertes Programmieren (Java) Java folgt gewissen Rechtschreibregeln die Syntax. Diese besagt, dass hinter jeden Befehl ein Semikolon( ; ) stehen muss, damit der Computer weiß, dass
MehrEin kleiner Blick auf die generische Programmierung
TgZero Technik.Blosbasis.net June 3, 2013 1 Inhaltsverzeichnis 1 Vorwort 3 2 Ein kleines Beispiel 3 3 Templates 3 4 Verschiedene Datentypen 4 5 Variadic Templates 5 6 Unterschied zwischen den Programmiersprachen
MehrDie Definition eines Typen kann rekursiv sein, d.h. Typ-Konstruktoren dürfen Elemente des zu definierenden Typ erhalten.
4.5.5 Rekursive Typen Die Definition eines Typen kann rekursiv sein, d.h. Typ-Konstruktoren dürfen Elemente des zu definierenden Typ erhalten. datatype IntList = Nil Cons o f ( i n t IntList ) ; Damit
MehrVorlesung Objektorientierte Programmierung Klausur
Prof. Dr. Stefan Brass 16. Februar 2007 Dipl.-Inform. Annett Thüring Institut für Informatik MLU Halle-Wittenberg Vorlesung Objektorientierte Programmierung Klausur Name: Matrikelnummer: Studiengang: Aufgabe
MehrÜBUNGS-BLOCK 7 LÖSUNGEN
ÜBUNGS-BLOCK 7 LÖSUNGEN Aufgabe 1: Gegeben ist folgender Code: Auto[] array = new Auto[3]; // Alle Autos im Array tunen: for (int i = 1; i
MehrProgrammiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny
Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny 7. Funktionen Einleitung Nach dem Prinzip Divide and Conquer bietet es sich an, größere Aufgaben in kleinere Teile zu unterteilen. Anweisungsblöcke,
MehrProInformatik: Funktionale Programmierung. Punkte
ProInformatik: Funktionale Programmierung 27.7-22.8.2008, M. Knobelsdorf Probeklausur Ihre persönliche Klausurnummer: Vorname, Nachname: Aufgabe 1 2 3 4 5 6 7 8 Punkte 12 4 4 4 4 2 4 6 40 Erz. Punkte Zum
MehrUmsetzung einer Klassenkarte in einer Programmiersprache
Klassen in Java Umsetzung einer Klassenkarte in einer Programmiersprache Objektorientierte Programme bestehen (nur) aus Klassendefinitionen In Klassendefinitionen wird die Struktur der Objekte festgelegt,
Mehrzu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme
Bisher Datentypen: einfach Zahlen, Wahrheitswerte, Zeichenketten zusammengesetzt Arrays (Felder) zur Verwaltung mehrerer zusammengehörender Daten desselben Datentypes eindimensional, mehrdimensional, Array-Grenzen
MehrIT I: Heute. Nachbetrachtung Wissensüberprüfung. Einführung Vererbung. Roboter in becker.robots. Filialenbelieferung 4.11.
IT I: Heute Nachbetrachtung Wissensüberprüfung Einführung Vererbung Roboter in becker.robots Filialenbelieferung 4.11.2014 IT I - VO 4 1 Organisatorisches Tutorium am Mi, 12.11. schon um 11 Uhr (bis 12:30).
MehrFunktionale Programmierung und Typtheorie
Funktionale Programmierung und Typtheorie 5. Fortgeschrittene Konzepte 5.1 Komprehensionen 5.2 Partielle Applikationen 5.3 Strikte und nichtstrikte Funktionen 5.4 Unendliche Datenstrukturen und verzögerte
MehrTypklassen. Natascha Widder
Typklassen Natascha Widder 19.11.2007 Motivation Typklassen fassen Typen mit ähnlichen Operatoren zusammen ermöglichen überladenen Funktionen Definition Typklassen Deklarationsschema class Name Platzhalter
MehrProgrammieren in Haskell Programmiermethodik
Programmieren in Haskell Programmiermethodik Peter Steffen Universität Bielefeld Technische Fakultät 12.01.2011 1 Programmieren in Haskell Bisherige Themen Was soll wiederholt werden? Bedienung von hugs
MehrTag 4 Repetitorium Informatik (Java)
Tag 4 Repetitorium Informatik (Java) Dozent: Michael Baer Lehrstuhl für Informatik 2 (Programmiersysteme) Friedrich-Alexander-Universität Erlangen-Nürnberg Wintersemester 2017/2018 Übersicht Arrays (Reihungen)
MehrGirls Day 2017 Programmierung
Girls Day 2017 Programmierung Anke Brocker Quality Management Würselen, 27. April 2017 www.lancom-systems.de Programmierung 27.04.2017 - Übersicht Programmieren mit der Arduino IDE Die Arduino IDE Der
Mehrzu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme
Bisher Datentypen: einfach Zahlen, Wahrheitswerte, Zeichenketten zusammengesetzt Arrays (Felder) zur Verwaltung mehrerer zusammengehörender Daten desselben Datentypes eindimensional, mehrdimensional, Array-Grenzen
Mehr7 Funktionen. 7.1 Definition. Prototyp-Syntax: {Speicherklasse} {Typ} Name ({formale Parameter});
S. d. I.: Programieren in C Folie 7-1 7 Funktionen 7.1 Definition Prototyp-Syntax: Speicherklasse Typ Name (formale Parameter); der Funktions-Prototyp deklariert eine Funktion, d.h. er enthält noch nicht
MehrÜbung zur Vorlesung Wissenschaftliches Rechnen Sommersemester 2012 Auffrischung zur Programmierung in C++, 2. Teil
MÜNSTER Übung zur Vorlesung Wissenschaftliches Rechnen Sommersemester 2012 Auffrischung zur Programmierung in C++ 2. Teil 18. April 2012 Organisatorisches MÜNSTER Übung zur Vorlesung Wissenschaftliches
MehrGrundlagen der Programmierung 2 (1.A)
Grundlagen der Programmierung 2 (1.A) Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie 20. April 2006 Grundlagen der Programmierung 2: Geplanter Inhalt der ersten Hälfte
MehrGrundlegende Datentypen
Grundlegende Datentypen (Funktionale Programmierung) Prof. Dr. Oliver Braun Letzte Änderung: 18.03.2018 21:08 Grundlegende Datentypen 1/16 Typen in Haskell ist alles streng typisiert Haskell verfügt über
MehrInformatik I Übung, Woche 40
Giuseppe Accaputo 1. Oktober, 2015 Plan für heute 1. Nachbesprechung Übung 2 2. Vorbesprechung Übung 3 3. Zusammenfassung der für Übung 3 wichtigen Vorlesungsslides Informatik 1 (D-BAUG) Giuseppe Accaputo
MehrProgrammsteuerung mit PHP - if/else, elseif,switch
Programmsteuerung mit PHP - if/else, elseif,switch Bei der Programmierung geht es meist vor allem darum festzulegen, welche Aktionen wie oft unter welchen Bedingungen ausgeführt werden sollen. Hierzu steht
MehrAlgorithmen und Programmieren 1 Funktionale Programmierung - Musterlösung zu Übung 9 -
Algorithmen und Programmieren 1 Funktionale Programmierung - Musterlösung zu Übung 9 - Dozent: Prof. Dr. G. Rote Tutoren: J. Fleischer, T. Haimberger, N. Lehmann, C. Pockrandt, A. Steen 10.01.2012 Ziele
MehrVorsemesterkurs Informatik
Vorsemesterkurs Informatik Sommersemester 2011 Grundlagen der Programmierung in Haskell SoSe 2011 Stand der Folien: 30. März 2011 Übersicht 1 Ausdrücke und Typen 2 Funktionen 3 Rekursion Vorkurs Informatik
Mehreinlesen n > 0? Ausgabe Negative Zahl
1 Lösungen Kapitel 1 Aufgabe 1.1: Nassi-Shneiderman-Diagramm quadratzahlen Vervollständigen Sie das unten angegebene Nassi-Shneiderman-Diagramm für ein Programm, welches in einer (äußeren) Schleife Integer-Zahlen
MehrFunktionen. mehrfach benötigte Programmteile nur einmal zu schreiben und mehrfach aufzurufen
Funktionen Funktionen erlauben, dem Programmcode hierarchisch zu strukturieren ein Hauptprogramm steuert dabei die Abfolge von Schritten, die einzelnen Schritte können durch Funktionen realisiert werden
Mehr1 Berechnung von Summen (ca = 10 Punkte)
Einführung in die wissenschaftliche Programmierung Klausur 26.02.2013 Seite 1/8 Name, Vorname, Unterschrift: Matrikelnummer: 1 Berechnung von Summen (ca. 5 + 4 + 1 = 10 Punkte) Gegeben sind natürliche
MehrProgrammieren I. Kapitel 5. Kontrollfluss
Programmieren I Kapitel 5. Kontrollfluss Kapitel 5: Kontrollfluss Ziel: Komplexere Berechnungen im Methodenrumpf Ausdrücke und Anweisungen Fallunterscheidungen (if, switch) Wiederholte Ausführung (for,
MehrKontrollstrukturen -- Schleifen und Wiederholungen
Kontrollstrukturen -- Schleifen und Wiederholungen Informatik für Elektrotechnik und Informationstechnik Benedict Reuschling benedict.reuschling@h-da.de Hochschule Darmstadt Fachbereich Informatik WS 2013/14
Mehr6. Funktionen, Parameterübergabe
6. Funktionen, Parameterübergabe GPS-6-1 Themen dieses Kapitels: Begriffe zu Funktionen und Aufrufen Parameterübergabearten call-by-value, call-by-reference, call-by-value-and-result in verschiedenen Sprachen
MehrAbschnitt 11: Korrektheit von imperativen Programmen
Abschnitt 11: Korrektheit von imperativen Programmen 11. Korrektheit von imperativen Programmen 11.1 11.2Testen der Korrektheit in Java Peer Kröger (LMU München) in die Programmierung WS 16/17 931 / 961
MehrKlausur: Grundlagen der Informatik I, am 27. März 2009 Gruppe: F Dirk Seeber, h_da, Fb Informatik. Nachname: Vorname: Matr.-Nr.
Seite 1 von 9 Hiermit bestätige ich, dass ich die Übungsleistungen als Voraussetzung für diese Klausur in folgender Übung erfüllt habe. Jahr: Übungsleiter: Unterschrift: 1. Aufgabe ( / 15 Pkt.) Was liefert
MehrGrundlegende Datentypen
Funktionale Programmierung Grundlegende Datentypen Fakultät für Informatik und Mathematik Hochschule München Letzte Änderung: 14.11.2017 15:37 Inhaltsverzeichnis Typen........................................
Mehr2 Eine einfache Programmiersprache
2 Eine einfache Programmiersprache Eine Programmiersprache soll Datenstrukturen anbieten Operationen auf Daten erlauben Kontrollstrukturen zur Ablaufsteuerung bereitstellen Als Beispiel betrachten wir
Mehr1. Klausur - Probeklausur
EI Info J2 2011-12 INFORMATIK 1. Klausur - Probeklausur Vorgeschlagene Bearbeitungszeit: 60 Minuten. In der Klausur wird es möglich sein, eine (zwei für Neue ) Teilaufgaben zu streichen! Hier sind mehr
MehrÜBUNGS-BLOCK 1 LÖSUNGEN
ÜBUNGS-BLOCK 1 LÖSUNGEN Aufgabe 1: Wenn dich jemand fragen würde, was er sich im Bezug auf die Programmierung unter einer Klasse vorstellen kann, was würdest du ihm sagen? Aus welchen Bestandteilen besteht
MehrMethoden. Gerd Bohlender. Einstieg in die Informatik mit Java, Vorlesung vom
Einstieg in die Informatik mit Java, Vorlesung vom 2.5.07 Übersicht 1 2 definition 3 Parameterübergabe, aufruf 4 Referenztypen bei 5 Überladen von 6 Hauptprogrammparameter 7 Rekursion bilden das Analogon
Mehr2 Eine einfache Programmiersprache
2 Eine einfache Programmiersprache Eine Programmiersprache soll Datenstrukturen anbieten Operationen auf Daten erlauben Kontrollstrukturen zur Ablaufsteuerung bereitstellen Als Beispiel betrachten wir
MehrWir betrachten noch einmal den Datentyp für blattbeschriftete Binärbäume
Zustandsmonaden Wir betrachten noch einmal den Datentyp für blattbeschriftete Binärbäume data Tree a = L a Tree a :+: Tree a und wollen eine Funktion definieren, die die Knoten so eines Baums von links
MehrWiederholungsklausur "ADP" WS 2016/2017
PD Dr. J. Reischer 23.02.2017 Wiederholungsklausur "ADP" WS 2016/2017 Nachname, Vorname Abschluss (BA, MA, FKN etc.) Matrikelnummer, Semester Versuch (1/2/3) Bitte füllen Sie zuerst den Kopf des Angabenblattes
MehrProgrammierkurs II. Typsynonyme & algebraische Datentypen
Programmierkurs II Typsynonyme & algebraische Datentypen Um Dinge der realen Welt abzubilden, ist es nur in den seltensten Fällen komfortabel alles als Zahlen, Strings oder Listen zu kodieren. Wir benötigen
Mehr