Haskell, Typen und Typberechnung
|
|
|
- Gerrit Gerstle
- vor 8 Jahren
- Abrufe
Transkript
1 Kapitel 5 Haskell, Typen und Typberechnung 5.1 Typisierung in Haskell In diesem Kapitel sind die Typisierungsmethoden in Haskell beschrieben, wobei auch kurz auf die Typisierung in anderen Programmiersprachen eingegangen wird. In Haskell gilt, dass jeder gültige Ausdruck einen Typ haben muss. Der Typchecker sorgt dafür, dass es keine Ausnahmen gibt. Diese Art des Typchecks nennt man starke statische Typisierung. Die Theorie sagt dann, dass nach erfolgreichem Typcheck keine Typfehler zur Laufzeit mehr auftreten können. Das Gegenteil ist dynamische Typisierung, die eine Typüberprüfung zur Laufzeit macht. D.h. es gibt ein Typsystem, alle Datenobjekte haben einen Typ, meist durch die Implementierung der Daten gegeben. Bei falschem Aufruf wird ein Laufzeit-Typfehler gemeldet. Die schwache, statische Typisierung hat einen Typcheck zur Kompilierzeit, aber es sind Löcher gelassen für den Programmierer, so dass in bestimmten Fällen entweder ein dynamischer Typcheck notwendig ist und eventuell doch ein Typfehler zur Laufzeit auftreten kann. Normalerweise haben alle Konstanten, Variablen (Bezeichner), Prozeduren und Funktionen einen im Programm festgelegten Typ. Typisch für diese Sprachen ist, dass man zur Laufzeit den Typ per Programmbefehl abfragen kann. Monomorphe Typisierung erzwingt, dass alle Objekte und insbesondere Funktionen einen eindeutigen Typ haben, d.h. Typvariablen sind verboten bzw. es gibt keine Allquantoren in den Typen. In Haskell würde das bedeuten, dass man für Listen von Zahlen und Listen von Strings verschiedene Längenfunktionen bräuchte. Polymorphe Typisierung erlaubt es, Funktionen zu schreiben, die auf mehreren Typen arbeiten können, wobei man schematische Typen meint. In Haskell sind die Typvariablen verantwortlich für die Schematisierung. Man 1
2 PRG 2, SS 2008, Typen, vom nennt dies auch parametrischen Polymorphismus. In dieser Typisierung ist es möglich, eine einzige Längenfunktion für alle Listen zu verwenden. Oft interpretiert man die polymorphe Typisierung auch so: Ein Ausdruck kann eine Menge von Typen haben (vielgestaltig, polymorph). Die (teilweise unendliche) Menge der Typen kann man dann oft in einem einzigen schematischen Typausdruck notieren. Die weitere Strukturierung der Typen in Typklassen ignorieren wir zunächst mal. Wir geben die Syntax von Typen in Haskell an: Definition Syntax der Haskell-Typen (ohne Typklassen-Information) Typ ::= Basistyp ( Typ ) Typvariable Typkonstruktor n { Typ } n (n ist dessen Stelligkeit) Basistyp ::= Int Integer Float Rational Char Typkonstruktoren können benutzerdefiniert sein (z.b. Baum.). Eingebaute Typkonstruktoren sind: Liste [ ], Tupel (.,...,.) für Stelligkeiten 2 und Funktion (Stelligkeit 2). Typen mit sind sogenannte Funktionstypen. Die Konvention ist, dass man normalerweise a b c d schreiben darf, und der gemeinte Typ dann durch Rechtsklammerung entsteht, d.h. a (b (c d)). Es gibt spezielle syntaktische Konventionen für Tupel und Listen. Zum Beispiel ist (Int, Char) der Typ eines Paars von Zahlen und Zeichen; [Int] ist der Typ einer Liste von Zahlen des Typs Int. Man verwendet den doppelten Doppelpunkt zur Typangabe. t :: τ soll bedeuten, dass der Ausdruck t den Typ τ hat. Dies ist syntaktisch auch in Haskell- Programmen erlaubt. Basistypen nennt man auch elementare Typen. Einen Typ nennt man auch Grundtyp, wenn er keine Typvariablen enthält. Einen solchen Typ nennt man manchmal auch monomorph. Einen Typ nennt man polymorph, wenn er Typvariablen enthält. Beispiel length :: [a] Int D.h. die Funktion length hat als Argument ein Objekt vom Typ [a], wobei a noch frei ist. Das Ergebnis muss vom Typ Int sein. Will man den Typ als Formel ausdrücken, so könnte man schreiben: a.length :: [a] Int Das kann man interpretieren als: Für alle Typen a ist length eine Funktion, die vom Typ [a] Int ist. Da das eine Aussage über Argumente und Resultate ist, sollte folgendes gelten: x.x :: [a] (length x) :: Int.
3 PRG 2, SS 2008, Typen, vom (:) :: a [a] [a]. Der Listenkonstruktor hat zwei Argumente. Das erste hat irgendeinen Typ a. Das zweite Argument ist eine Liste, deren Elemente vom Typ a, d.h. von gleichem Typ wie das erste Argument sein müssen. Das Ergebnis ist eine Liste vom Typ [a]. map :: (a b) [a] [b] beschreibt den Typ der Funktion map Typregeln Die wichtigste Typregel in Haskell, die auch in anderen Programmiersprachen mit monomorphem Typsystem gilt, betrifft die Anwendung von Funktionen auf Argumente: Wenn σ, τ Typen sind, dann gilt die Regel: s :: σ τ, t :: σ (s t) :: τ Zum Beispiel ist die Anwendung der Funktion quadrat :: Int Int auf eine Zahl 2 : Int. D.h. quadrat 2 :: Int. Wenn man z.b. die Funktion + anwendet, mit dem Typ + :: Int Int Int, dann erhält man für (1 + 2) die voll geklammerte Version ((+ 1) 2). (+ 1) hat dann den Typ (Int Int), und ((+ 1) 2) den Typ Int. Man kann auch die Regel im Fall mehrerer Argumente etwas einfacher handhaben, indem man sofort alle Argumenttypen einsetzt. Die zugehörige Regel ist dann s :: σ 1 σ 2... σ n τ, t 1 :: σ 1,..., t n :: σ n (s t 1... t n ) :: τ Zum Beispiel ergibt das für (+ 1 2): + :: Int Int Int, 1 :: Int, 2 :: Int (+ 1 2) :: Int Dies lässt sich noch nicht so richtig auf die Funktion length oder map anwenden. Da die Haskelltypen aber Typvariablen enthalten können, formulieren wir die erste Regel etwas allgemeiner, benötigen dazu aber den Begriff der Instanz eines Typs. Definition Wenn γ eine Funktion auf Typen ist, die Typen für Typvariablen einsetzt, dann ist γ eine Typsubstitution. Wenn τ ein Typ ist, denn nennt man γ(τ) eine Instanz von τ. Beispiel Man kann mit γ = {a Char, b Float} die Instanz γ([a] Int) = [Char] Int bilden. Die Regel für die Anwendung lautet dann: s : σ τ, t : ρ und γ(σ) = γ(ρ) (s t) :: γ(τ) wobei die Typvariablen ρ umbenannt sind
4 PRG 2, SS 2008, Typen, vom Die Umbenennung soll so sein, dass die Mengen der Typvariablen von sigma τ und ρ disjunkt sind, damit keine ungewollten Konflikte entstehen. Beispiel Die Anwendung für den Ausdruck map quadrat ergibt folgendes. Zunächst ist map :: (a b) [a] [b] Instanziiert man das mit der Typsubstitution {a Int, b Int}, dann erhält man, dass map u.a. den Typ (Int Int) [Int] [Int] hat. Damit kann man dann die Regel verwenden: map : (Int Int) [Int] [Int], quadrat :: (Int Int) (map quadrat) :: [Int] [Int] Die Erweiterung auf eine Funktion mit n Argumenten, wenn γ eine Typsubstitution ist, sieht so aus: s :: σ 1 σ 2... σ n τ, t 1 : ρ 1,..., t n : ρ n und i : γ(σ i ) = γ(ρ i ) (s t 1... t n ) :: γ(τ) Auch hierbei müssen die Mengen der Typvariablen von σ 1 σ 2... σ n τ einerseits und ρ 1,..., ρ n andererseits, disjunkt sein. Bei diesen Regeln ist zu beachten, dass man das allgemeinste γ nehmen muss, um den Typ des Ergebnisses zu ermitteln. Nimmt man irgendeine andere, passende Typsubstitution, dann erhält man i.a. einen zu speziellen Typ. Beispiel Betrachte die Funktion id mit der Definition id x = x und dem Typ a a. Um Konflikte zu vermeiden, nehmen wir hier a a Der Typ von (map id) kann berechnet werden, wenn man obige Regel mit der richtigen Typsubstitution benutzt. Der Typ des ersten Arguments von map muss a b sein, und id erzwingt, dass a = b. Die passende Typsubstitution ist γ = {b a, a a}. Das ergibt unter Anwendung der Regel d.h. (map id) :: ([a] [a]). map : (a b) ([a] [b]), id :: a a (map id) :: γ([a] [b]) Berechnen der Typsubstitution Im folgenden zeigen wir, wie man die Typsubstitution γ nicht nur geschickt rät, sondern ausrechnet, wenn man Typen δ i, ρ i, i = 1,..., n gegeben hat, die nach der Einsetzung gleich sein müssen. Diese Berechnung nennt man auch Unifikation. γ muss so gewählt werden, dass folgendes gilt i : γ(δ i ) = γ(ρ i ). Man kann dieses Gleichungssystem umformen bzw. zerlegen.
5 PRG 2, SS 2008, Typen, vom Der Algorithmus operiert auf einem Paar aus einer Lösung G und einer Multimenge E von Gleichungen. T C bezeichnet Typkonstruktoren, a eine Typvariable, σ, τ (polymorphe) Typen. Wir dürfen folgende Regeln zur Umformung des Gleichungssystems δ i. = ρ i, i = 1,..., n benutzen, wobei wir mit G = starten. (Dekomposition) G ; {(T C σ 1... σ m ). = (T C τ 1... τ m )} E G ; {σ 1. = τ1,..., σ m. = τn } E Wenn die Typkonstruktoren rechts und links verschieden sind, dann kann man die Berechnung abbrechen; es kann keine Lösung geben. (Ersetzung) G ; {a. = σ} E G {a σ} ; E[σ/a] Wenn a nicht in σ vorkommt wobei E[σ/a] bedeutet: Ersetze alle Vorkommen der Typvariablen a durch den Typ σ, und G[σ/a] bedeutet: Ersetze in alle Lösungenskomponenten x s durch x s[σ/a]. Hierbei ist wegen der Terminierung der Berechnung darauf zu achten, dass σ die Typvariable a nicht enthält, da man sonst bei der Berechnung keinen Fortschritt erzielt, bzw. die Berechnung nicht terminiert. Man kann auch zeigen, dass es in diesem Fall keine Lösung gibt. (V ereinf achung) G ; {a. = a} E G ; E (V ertauschung) G ; {σ. = a} E G ; {a. = σ} E Wir sind fertig, wenn E leer ist. Dann hat G die Form a 1 τ 1,..., a k τ k t, wobei a i Typvariablen sind, und die a i in keiner rechten Seite τ j einer Gleichung auftreten. Die Typsubstitution ist dann direkt ablesbar. Die Korrektheit des Verfahrens wollen wir hier nicht zeigen, aber es ist offensichtlich, dass die so berechnete Substitution das letzte Gleichungssystem erfüllt. Es lautet nach der Substitution: τ 1 = τ 1,... τ k = τ k. Jetzt muss man für jede der Regeln zeigen, dass sie diese Korrektheit erhält. Beispiel Bei der Typisierung für (map id) zeigt sich, dass man je nach Regelanwendung unterschiedliche Typsubstitutionen finden kann: Die eigentliche Typisierung ist: Berechnen von γ: map :: (a b) [a] [b], id :: a a (map id) :: γ([a] [b])
6 PRG 2, SS 2008, Typen, vom G E a b =. a a a =. a, b =. a a a b =. a a a, b a Das ergibt die Typsubstitution γ = {a a, b a } Eine andere Berechnung von γ mit einer Vertauschung ergibt: G a a a a, a b Das ergibt die Typsubstitution E a a. = a b a. = a, a. = b a =. b γ = {a a, a b} Wir erhalten dann entweder (map id):: [a ] [a ] oder (map id):: [b] [b], was jedoch aufgrund der All-Quantifizierung bis auf Umbenennung identische Typen sind. Definition Sei V eine Menge von Typvariablen und γ, γ zwei Typsubstitutionen. Dann ist γ allgemeiner als γ (bzgl. V ), wenn es eine weitere Typsubstitution δ gibt, so dass für alle Variablen x V : δ(γ(x)) = γ (x). Um das zum Vergleich von Typsubstitutionen anzuwenden, nimmt man normalerweise V als Menge der Typvariablen die in der Typgleichung vor der Unifikation enthalten sind. Beispiel Nimmt man V = {a 1 }, dann ist γ = {a 1 (a 2, b 2 )} allgemeiner als γ = {a 1 (Int, Int)}, denn man kann γ durch weitere Instanziierung von γ erhalten: Nehme δ = {a 2 Int, b 2 Int}. Dann ist δ(γ(a 1 )) = (Int, Int) = γ (a 1 ). Beispiel Der Typ der Liste [1] kann folgendermaßen ermittelt werden: [1] = 1 : [] 1 :: Int und [] :: [b] folgt aus den Typen der Konstanten. (:) :: a [a] [a] Anwendung der Regel mit γ = {a Int} ergibt: (1 :) :: [Int] [Int]
7 PRG 2, SS 2008, Typen, vom Nochmalige Anwendung der Regel mit γ = {b Int} ergibt: (1 : []) :: [Int] Beispiel Wir weisen nach, dass es keinen Typ von [1, a ] gibt: Der voll geklammerte Ausdruck ist 1 : ( a : []). 1 :: Int, [] :: [b] und a :: Char folgen aus den Typen der Konstanten. Wie oben ermittelt man: (1 :) :: [Int] [Int] und a :[] :: [Char]. Wenn wir jetzt die Typregel anwenden wollen, dann stellen wir fest: es gibt kein γ, das [Int] und [Char] gleichmacht. D.h. die Regel ist nicht anwendbar. Da das auch der allgemeinste Versuch war, einen Typ für diese Liste zu finden, haben wir nachgewiesen, dass die Liste [1, a ] keinen Typ hat; d.h. der Typchecker wird sie zurückweisen. > [1, a ] ERROR - Illegal Haskell 98 class constraint in inferred type *** Expression : [1, a ] *** Type : Num Char => [Char] Beispiel Wir zeigen, wie der Typ von (map quadrat [1,2,3,4]) ermittelt wird. map hat den Typ (a b) [a] [b] quadrat den Typ Integer Integer, und [1, 2, 3, 4] :: [Integer]. Wir nehmen γ = {a Integer, b Integer}. Das ergibt γ(a) = Integer, γ([a]) = [Integer], γ([b]) = [Integer]. Damit ergibt sich mit obiger Regel, dass das Resultat vom Typ γ([b]) = [Integer] ist. Etwas komplexer ist die Typisierung von definierten Funktionen, insbesondere von rekursiv definierten. Man benötigt auch weitere Regeln für Lambda- Ausdrücke, let-ausdrücke und List-Komprehensionen. In Haskell und ML wird im wesentlichen der sogenannte Typcheckalgorithmus von Robin Milner verwendet. Dieser ist i.a. schnell, aber hat eine sehr schlechte worst-case Komplexität: in seltenen Fällen hat er exponentiellen Platzbedarf. Dieser Algorithmus liefert allgemeinste Typen im Sinne des Milnerschen Typsystems. Allerdings nicht immer die allgemeinsten möglichen polymorphen Typen. Folgender Satz gilt im Milner-Typsystem. Wir formulieren ihn für Haskell. Satz Sei t ein getypter Haskell-Ausdruck, der keine freien Variablen enthält (d.h. der geschlossen ist). Dann wird die Auswertung des Ausdrucks t nicht mit einem Typfehler abbrechen.
8 PRG 2, SS 2008, Typen, vom Dieser Satz sollte auch in allen streng typisierten Programmiersprachen gelten, sonst ist die Typisierung nicht viel wert. Wir untermauern den obigen Satz, indem wir uns die Wirkung der Beta- Reduktion auf die Typen der beteiligten Ausdrücke anschauen. ((λx.t) s) Erinnerung Beta-Reduktion:. t[s/x] Der Typ von λx.t sei τ 1 τ 2. Der Typ von s sei σ. Damit der Ausdruck ((λx.t) s) einen Typ hat, muss es eine (allgemeinste) Typsubstitution γ geben, so dass γ(τ 1 ) = γ(σ) ist. Der Ausdruck hat dann den Typ γ(τ 2 ). Jetzt verwenden wir γ um etwas über den Typ des Resultatterms t[s/x] herauszufinden. Dazu muss man wissen, dass der Milner-Typcheck nur den Typ der Unterterme beachtet, nicht aber deren genaue Form. Verwendet man γ, dann hat unter γ der Ausdruck s und die Variable x den gleichen Typ; jeweils als Unterterme von t betrachtet. D.h. Der Typ von t[s/x] ist unter der Typsubstitution γ gerade γ(τ 2 ). Da man das für jede Typsubstitution machen kann, kann man daraus schließen, dass die Beta-Reduktion den Typ erhält. Leider ist die Argumentation etwas komplizierter, wenn die Beta-Reduktion innerhalb eines Terms gemacht wird, d.h. wenn t Unterausdruck eines anderen Ausdrucks ist, aber auch in diesem Fall gilt die Behauptung, dass die Beta- Reduktion den Typ nicht ändert. Analog kann man die obige Argumentation für andere Auswertungsregeln verwenden Bemerkungen zu anderen Programmiersprachen In den funktionalen Programmiersprachen Lisp und Scheme, die beide höherer Ordnung sind, gibt es in den Standardvarianten kein statisches Typsystem. Der Grund ist, dass schon in den ersten Konzeptionen dieser Sprachen keine statische Typdisziplin eingehalten wurde: Z.B. ist es erlaubt und wird auch genutzt, dass man alle Werte als Boolesche Werte verwenden darf: Die Konvention ist: Nil = False, alles andere gilt als True. Z.B. ist der Wert von 1 = 0 in Lisp die Konstante Nil, während 1 = 1 die Konstante 1 ergibt. Damit hat man Ausdrücke, die sowohl Boolesche Ausdrücke sind als auch Listen; und Ausdrücke, die Boolesche Ausdrücke sind und Zahlen. Als weitere Schwierigkeit kommen die Typeffekte von Zuweisungen hinzu. D.h. um einen vernünftigen Typisierungsalgorithmus für diese Programmiersprachen zu konzipieren, müsste man zu viel ändern. Programmiersprachen, die keine Funktionen oder Prozeduren höherer Ordnung haben, begnügen sich meist mit einem monomorphen Typcheck. Bei Verwendung der arithmetischen Operatoren, z.b. des Additionszeichens (+) will man oft erreichen, dass dies für alle Zahlentypen wie Int, Rational usw. funktioniert. In manchen Programmiersprachen wird vom Compiler automatisch eine Typkonversion eingefügt, wenn unverträgliche Zahltypen benutzt werden.
9 PRG 2, SS 2008, Typen, vom In Haskell sind eingegebene Zahlkonstanten normalerweise überladen, indem z.b. bei Eingabe der Zahl 1 vom Compiler frominteger 1 eingefügt wird. Wenn unverträgliche Operanden benutzt werden, muss man die Typkonversion von Hand einfügen. Z.B. pi + 2%3 ergibt einen Typfehler, während pi + (fromrational (2%3)) korrekt ::Double ergibt. Die Programmiersprache Python ist ungetypt. Man könnte vermutlich ein monomorphes Typsystem zu Python hinzufügen, allerdings hat Python bisher keine syntaktischen Elemente, um den Typ einer Variablen festzulegen. Als weitere Schwierigkeit kommt hinzu, dass Python Lambda-Ausdrücke zulässt. Diese Kombination erlaubt mit Sicherheit kein strenges Typsystem, es sei denn, man nimmt hin, dass viele in normalem Python erlaubten Programme in getypten Python verboten wären. Die Programmiersprache Java ist streng getypt. Das Typsystem ist monomorph, allerdings entsprechen die Java-Klassen den elementaren Typen. Zudem gibt es einen Untertyp-Begriff für Klassen, d.h. für die elementaren Typen. Die Typfehler, die jetzt noch auftreten, sind meist von der Art, dass ein syntaktisch geforderter Typ nicht mit dem aktuellen Objekt übereinstimmt, d.h. Fehler beim (cast).
Haskell, Typen, und Typberechnung. Grundlagen der Programmierung 3 A. Einige andere Programmiersprachen. Typisierung in Haskell
Haskell, Typen, und Typberechnung Grundlagen der Programmierung 3 A Typen, Typberechnung und Typcheck Prof. Dr. Manfred Schmidt-Schauß Ziele: Haskells Typisierung Typisierungs-Regeln Typ-Berechnung Milners
Programmieren 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
Programmieren 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
Lösungen zum Aufgabenblatt 10 Logik und modelltheoretische Semantik
Lösungen zum Aufgabenblatt 10 Logik und modelltheoretische Semantik Universität München, CIS, SS 2013 Hans Leiß Abgabetermin: Do, 4.7.2013, 16 Uhr, in meinem Postfach Aufgabe 10.1 Vereinfache die folgenden
Verarbeitung unendlicher Datenstrukturen Jetzt können wir z.b. die unendliche Liste aller geraden Zahlen oder aller Quadratzahlen berechnen:
Verarbeitung unendlicher Datenstrukturen Jetzt können wir z.b. die unendliche Liste aller geraden Zahlen oder aller Quadratzahlen berechnen: take 1 0 ( f i l t e r ( fn x => x mod 2=0) nat ) ; val it =
Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 12/13. Kapitel 3. Grunddatentypen, Ausdrücke und Variable
1 Kapitel 3 Grunddatentypen, Ausdrücke und Variable 2 Eine Datenstruktur besteht aus Grunddatentypen in Java einer Menge von Daten (Werten) charakteristischen Operationen Datenstrukturen werden mit einem
3 Terme und Algebren 3.1 Terme
3 Terme und Algebren 3.1 Terme Mod - 3.1 In allen formalen Kalkülen benutzt man Formeln als Ausdrucksmittel. Hier betrachten wir nur ihre Struktur - nicht ihre Bedeutung. Wir nennen sie Terme. Terme bestehen
Programmieren 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
Kapitel 4. Programmierkurs. Datentypen. Arten von Datentypen. Wiederholung Kapitel 4. Birgit Engels, Anna Schulze WS 07/08
Kapitel 4 Programmierkurs Birgit Engels, Anna Schulze Wiederholung Kapitel 4 ZAIK Universität zu Köln WS 07/08 1 / 23 2 Datentypen Arten von Datentypen Bei der Deklaration einer Variablen(=Behälter für
Programmieren 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
Beispiele: (Funktionen auf Listen) (3) Bemerkungen: Die Datenstrukturen der Paare (2) Die Datenstrukturen der Paare
Beispiele: (Funktionen auf Listen) (3) Bemerkungen: 5. Zusammenhängen der Elemente einer Liste von Listen: concat :: [[a]] -> [a] concat xl = if null xl then [] else append (head xl) ( concat (tail xl))
Java Einführung VARIABLEN und DATENTYPEN Kapitel 2
Java Einführung VARIABLEN und DATENTYPEN Kapitel 2 Inhalt dieser Einheit Variablen (Sinn und Aufgabe) Bezeichner Datentypen, Deklaration und Operationen Typenumwandlung (implizit/explizit) 2 Variablen
Beispiel. Problem: mehrteilige Nachnamen (von Goethe, Mac Donald, Di Caprio)
Beispiel Beispiel: Namensliste konvertieren (Karl Egon Meier Meier, Karl Egon). s/(.*) (.*)/$2, $1/; Problem: mehrteilige Nachnamen (von Goethe, Mac Donald, Di Caprio) s/(.*) (.*)/$2, $1/; s/(.*) ([a-z]+
Kapitel 3: Variablen
Kapitel 3: Variablen Thema: Programmieren Seite: 1 Kapitel 3: Variablen Im letzten Kapitel haben wir gelernt, bestimmte Ereignisse zu wiederholen solange eine Bedingung erfüllt ist. Nun möchten wir aber
Werkzeuge zur Programmentwicklung
Werkzeuge zur Programmentwicklung B-15 Bibliothek Modulschnittstellen vorübersetzte Module Eingabe Editor Übersetzer (Compiler) Binder (Linker) Rechner mit Systemsoftware Quellmodul (Source) Zielmodul
Elementare Konzepte von
Elementare Konzepte von Programmiersprachen Teil 1: Bezeichner, Elementare Datentypen, Variablen, Referenzen, Zuweisungen, Ausdrücke Kapitel 6.3 bis 6.7 in Küchlin/Weber: Einführung in die Informatik Bezeichner
ALP I Einführung in Haskell
ALP I Einführung in Haskell WS 2012/2013 Was ist Haskell? Haskell ist eine rein Funktionale Programmiersprache mit einer nach Bedarf Auswertung-Strategie oder "Lazy Evaluation". Was bedeutet rein funktional?
Was bisher geschah. deklarative Programmierung. funktionale Programmierung (Haskell):
Was bisher geschah deklarative Programmierung funktional: Programm: Menge von Termgleichungen, Term Auswertung: Pattern matsching, Termumformungen logisch: Programm: Menge von Regeln (Horn-Formeln), Formel
Grundprinzipien der funktionalen Programmierung
Grundprinzipien der funktionalen Programmierung Funktionen haben keine Seiteneffekte Eine Funktion berechnet einen Ausgabewert der nur von den Eingabewerten abhängt: 12 inputs + output 46 34 2 Nicht nur
JAVA-Datentypen und deren Wertebereich
Folge 8 Variablen & Operatoren JAVA 8.1 Variablen JAVA nutzt zum Ablegen (Zwischenspeichern) von Daten Variablen. (Dies funktioniert wie beim Taschenrechner. Dort können Sie mit der Taste eine Zahl zwischenspeichern).
Das Typsystem von Scala. L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala
Das Typsystem von Scala 1 Eigenschaften Das Typsystem von Scala ist statisch, implizit und sicher 2 Nichts Primitives Alles ist ein Objekt, es gibt keine primitiven Datentypen scala> 42.hashCode() res0:
Kapitel 11. Prädikatenlogik Quantoren und logische Axiome
Kapitel 11 Prädikatenlogik Im Kapitel über Aussagenlogik haben wir die Eigenschaften der Booleschen Operationen untersucht. Jetzt wollen wir das als Prädikatenlogik bezeichnete System betrachten, das sich
Terme und Gleichungen
Terme und Gleichungen Rainer Hauser November 00 Terme. Rekursive Definition der Terme Welche Objekte Terme genannt werden, wird rekursiv definiert. Die rekursive Definition legt zuerst als Basis fest,
Funktionale Programmierung mit Haskell
Funktionale Programmierung mit Haskell Dr. Michael Savorić Hohenstaufen-Gymnasium (HSG) Kaiserslautern Version 20120622 Überblick Wichtige Eigenschaften Einführungsbeispiele Listenerzeugung und Beispiel
Verkettete Datenstrukturen: Bäume
Verkettete Datenstrukturen: Bäume 1 Graphen Gerichteter Graph: Menge von Knoten (= Elementen) + Menge von Kanten. Kante: Verbindung zwischen zwei Knoten k 1 k 2 = Paar von Knoten (k 1, k 2 ). Menge aller
Typdeklarationen. Es gibt in Haskell bereits primitive Typen:
Typdeklarationen Es gibt in bereits primitive Typen: Integer: ganze Zahlen, z.b. 1289736781236 Int: ganze Zahlen mit Computerarithmetik, z.b. 123 Double: Fließkommazahlen, z.b. 3.14159 String: Zeichenketten,
Lineare Gleichungssysteme
Poelchau-Oberschule Berlin A. Mentzendorff September 2007 Lineare Gleichungssysteme Inhaltsverzeichnis 1 Grundlagen 2 2 Das Lösungsverfahren von Gauß 4 3 Kurzschreibweise und Zeilensummenkontrolle 6 4
Funktionale Programmierung mit Haskell. Jan Hermanns
Funktionale Programmierung mit Haskell Jan Hermanns 1 Programmiersprachen imperativ deklarativ konventionell OO logisch funktional Fortran Smalltalk Prolog Lisp C Eiffel ML Pascal Java Haskell 2 von Neumann
2.5 Primitive Datentypen
2.5 Primitive Datentypen Wir unterscheiden 5 primitive Datentypen: ganze Zahlen -2, -1, -0, -1, -2,... reelle Zahlen 0.3, 0.3333..., π, 2.7 10 4 Zeichen a, b, c,... Zeichenreihen "Hello World", "TIFI",
Kapitel 3. Grunddatentypen, Ausdrücke und Variable
Kapitel 3 Grunddatentypen, Ausdrücke und Variable Grunddatentypen, Ausdrücke und Variable 1 Eine Datenstruktur besteht aus Grunddatentypen in Java einer Menge von Daten (Werten) charakteristischen Operationen
Tableaukalkül für Aussagenlogik
Tableaukalkül für Aussagenlogik Tableau: Test einer Formel auf Widersprüchlichkeit Fallunterscheidung baumförmig organisiert Keine Normalisierung, d.h. alle Formeln sind erlaubt Struktur der Formel wird
Einführung in die Funktionale Programmierung: Einleitung & Motivation
Einführung in die Funktionale Programmierung: Einleitung & Motivation Prof Dr. Manfred Schmidt-Schauß WS 2011/12 Stand der Folien: 25. Oktober 2011 Motivation Funktionale Programmiersprachen Haskell Übersicht
Ausdrücke und primitive Typen
Lehrstuhl für Bioinformatik Einführung in die Programmierung für Bioinformatiker Prof. B. Rost, Dr. L. Richter Blatt 04 14.11.2016 Ausdrücke und primitive Typen Aufgabe 4.1 Java-Quiz Wahr Falsch Der Ausdruck
Welche Informatik-Kenntnisse bringen Sie mit?
Welche Informatik-Kenntnisse bringen Sie mit? So gehen Sie vor! Lösen Sie die Aufgaben der Reihe nach von 1 bis 20, ohne das Lösungsblatt zur Hilfe zu nehmen. Der Schwierigkeitsgrad der Aufgaben nimmt
Funktionale Programmierung ALP I. λ Kalkül WS 2012/2013. Prof. Dr. Margarita Esponda. Prof. Dr. Margarita Esponda
ALP I λ Kalkül WS 2012/2013 Berechenbarkeit - inspiriert durch Hilbert's Frage - im Jahr 1900, Paris - Internationaler Mathematikerkongress Gibt es ein System von Axiomen, aus denen alle Gesetze der Mathematik
FACHHOCHSCHULE AUGSBURG Hochschule für Technik, Wirtschaft und Gestaltung
C Sprachelemente für Übung 2 Typumwandlungen (type casts) Bei Ausdrücken, in denen Operanden mit unterschiedlichem Typ vorkommen, werden diese vom Compiler vor der Ausführung automatisch in einen gemeinsamen
Algorithmen & Programmierung. Ausdrücke & Operatoren (1)
Algorithmen & Programmierung Ausdrücke & Operatoren (1) Ausdrücke Was ist ein Ausdruck? Literal Variable Funktionsaufruf Ausdruck, der durch Anwendung eines einstelligen (unären) Operators auf einen Ausdruck
Programmierung 1 (Wintersemester 2015/16) Wiederholungstutorium Lösungsblatt 11 (Parser II)
Fachrichtung 6.2 Informatik Universität des Saarlandes Tutorenteam der Vorlesung Programmierung 1 Programmierung 1 (Wintersemester 2015/16) Wiederholungstutorium Lösungsblatt 11 (Parser II) Hinweis: Dieses
Einstieg in die Informatik mit Java
1 / 22 Einstieg in die Informatik mit Java Generics Gerd Bohlender Institut für Angewandte und Numerische Mathematik Gliederung 2 / 22 1 Überblick Generics 2 Generische Klassen 3 Generische Methoden 4
Syntax der Prädikatenlogik: Komplexe Formeln
Syntax der Prädikatenlogik: Komplexe Formeln Σ = P, F eine prädikatenlogische Signatur Var eine Menge von Variablen Definition: Menge For Σ der Formeln über Σ Logik für Informatiker, SS 06 p.10 Syntax
Allgemeine Hinweise: TECHNISCHE UNIVERSITÄT MÜNCHEN. Name Vorname Studiengang Matrikelnummer. Hörsaal Reihe Sitzplatz Unterschrift
TECHNISCHE UNIVERSITÄT MÜNCHEN FAKULTÄT FÜR INFORMATIK Lehrstuhl für Sprachen und Beschreibungsstrukturen WS 2008/09 Einführung in die Informatik 2 Klausur Prof. Dr. Helmut Seidl, T. M. Gawlitza, S. Pott,
Ausdrücke. Variable, Typ, Kontext, Deklaration, Initialisierung, Ausdruck, Syntax, Semantik, Seiteneffekt
Ausdrücke Variable, Typ, Kontext, Deklaration, Initialisierung, Ausdruck, Syntax, Semantik, Seiteneffekt Variablen als Stellvertreter In der Mathematik Variable ist Stellvertreter eines Wertes ändert sich
Demo für
SUMMENZEICHEN Regeln und Anwendungen Gebrauchs des Summenzeichens mit Aufgaben aus vielen Bereichen für Angela Datei Nr. 4 Stand:. Oktober INTERNETBIBLIOTHEK FÜR SCHULMATHEMATIK Demo für 4 Summenzeichen
C-Deklarationen lesen und schreiben
C-Deklarationen lesen und schreiben Version 1.2 6.7.2009 email: [email protected] Web: www.ostc.de Die Informationen in diesem Skript wurden mit größter Sorgfalt erarbeitet. Dennoch können Fehler nicht vollständig
Der Datentyp String. Stringvariable und -vergleiche
Informatik 12 mit Java: Gierhardt Zeichenketten bzw. Strings Der Datentyp String Zeichenketten bzw. Strings sind eine häufig benutzte Datenstruktur. Man könnte auch mit Arrays aus Zeichen arbeiten. Da
Funktionale Programmierung
FP-1.0 Funktionale Programmierung Prof. Dr. Uwe Kastens SS 2013 Vorlesung Funktionale Programmierung SS 2013 / Folie 100 Begrüßung Functional Programming is Fun FP-1.1 Fun ctional Programming is Fun ctional
Wertebereich und Genauigkeit der Zahlendarstellung
Wertebereich und Genauigkeit der Zahlendarstellung Sowohl F als auch C kennen bei ganzen und Floating Point-Zahlen Datentypen verschiedener Genauigkeit. Bei ganzen Zahlen, die stets exakt dargestellt werden
Grundlagen der Programmierung 2 (1.C)
Grundlagen der Programmierung 2 (1.C) Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie 3. Mai 2006 Funktionen auf Listen: map map :: (a -> b) -> [a] -> [b] map f [] = []
Einstieg in die Informatik mit Java
1 / 34 Einstieg in die Informatik mit Java Klassen mit Instanzmethoden Gerd Bohlender Institut für Angewandte und Numerische Mathematik Gliederung 2 / 34 1 Definition von Klassen 2 Methoden 3 Methoden
Kapitel 9. Komplexität von Algorithmen und Sortieralgorithmen
1 Kapitel 9 Komplexität von Algorithmen und Sortieralgorithmen Ziele 2 Komplexität von Algorithmen bestimmen können (in Bezug auf Laufzeit und auf Speicherplatzbedarf) Sortieralgorithmen kennenlernen:
Einführung in die Informatik Turing Machines
Einführung in die Informatik Turing Machines Eine abstrakte Maschine zur Präzisierung des Algorithmenbegriffs Wolfram Burgard Cyrill Stachniss 1/14 Motivation und Einleitung Bisher haben wir verschiedene
2. Symmetrische Gruppen
14 Andreas Gathmann 2 Symmetrische Gruppen Im letzten Kapitel haben wir Gruppen eingeführt und ihre elementaren Eigenschaften untersucht Wir wollen nun eine neue wichtige Klasse von Beispielen von Gruppen
37 Gauß-Algorithmus und lineare Gleichungssysteme
37 Gauß-Algorithmus und lineare Gleichungssysteme 37 Motivation Lineare Gleichungssysteme treten in einer Vielzahl von Anwendungen auf und müssen gelöst werden In Abschnitt 355 haben wir gesehen, dass
Wissensbasierte Systeme
WBS4 Slide 1 Wissensbasierte Systeme Vorlesung 4 vom 03.11.2004 Sebastian Iwanowski FH Wedel WBS4 Slide 2 Wissensbasierte Systeme 1. Motivation 2. Prinzipien und Anwendungen 3. Logische Grundlagen 4. Suchstrategien
Grundlagen der Informatik. Prof. Dr. Stefan Enderle NTA Isny
Grundlagen der Informatik Prof. Dr. Stefan Enderle NTA Isny 2 Datenstrukturen 2.1 Einführung Syntax: Definition einer formalen Grammatik, um Regeln einer formalen Sprache (Programmiersprache) festzulegen.
Lineare Algebra I (WS 12/13)
Lineare Algebra I (WS 12/13) Alexander Lytchak Nach einer Vorlage von Bernhard Hanke, Universität Augsburg 15.10.2013 Alexander Lytchak 1 / 14 Organisation Alle wichtigen organisatorischen Information
Strukturelle Rekursion und Induktion
Kapitel 2 Strukturelle Rekursion und Induktion Rekursion ist eine konstruktive Technik für die Beschreibung unendlicher Mengen (und damit insbesondere für die Beschreibung unendliche Funktionen). Induktion
4. Objektrelationales Typsystem Kollektionstypen. Nested Table
Nested Table Bei einer Nested Table handelt es sich um eine Tabelle als Attributwert. Im Gegensatz zu Varray gibt es keine Beschränkung bei der Größe. Definition erfolgt auf einem Basistyp, als Basistypen
zu 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
Programmieren in Haskell Einführung
Programmieren in Haskell Einführung Peter Steffen Universität Bielefeld Technische Fakultät 16.10.2009 1 Programmieren in Haskell Veranstalter Dr. Peter Steffen Raum: M3-124 Tel.: 0521/106-2906 Email:
1. Der Begriff Informatik 2. Syntax und Semantik von Programmiersprachen. I.2. I.2. Grundlagen von von Programmiersprachen.
1. Der Begriff Informatik 2. Syntax und Semantik von Programmiersprachen I.2. I.2. Grundlagen von von Programmiersprachen. - 1 - 1. Der Begriff Informatik "Informatik" = Kunstwort aus Information und Mathematik
Objektorientierte Programmierung OOP Programmieren mit Java
Objektorientierte Programmierung OOP Programmieren mit Java 5.1 Elementare Anweisungen 5.1.1 Ausdrucksanweisung 5.1.2 Leere Anweisung 5.1.3 Blockanweisung 5.1.4 Variablendeklaration 5.2 Bedingungen 5.2.1
Probeklausur: 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,
Die einfachsten Anweisungen
2 Die einfachsten Anweisungen 2-1 Inhalt Die einfachsten Anweisungen Einführung Datentypen Arithmetische Operatoren Mathematische Funktionen Mehrfache Zuweisungen Übungsaufgaben Einführung Wir wollen unser
1. Abstrakte Klassen
1. Abstrakte Klassen Lernziele 1. Abstrakte Klassen Lernziele: Das Konzept abstrakter Klassen und abstrakter Methoden kennen und verstehen, in der Lage sein, abstrakte Klassen und Methoden in Java zu formulieren,
Programmieren in Haskell
Programmieren in Haskell Syntax und Semantik von Haskell Programmieren in Haskell 1 Was wir heute (und nächstes mal) machen Datentypdefinitionen Wertdefinitionen, Variablenbindungen Musterbindungen Funktionsbindungen
Einführung in die Programmierung 1
Einführung in die Programmierung 1 Einführung (S.2) Einrichten von Eclipse (S.4) Mein Erstes Programm (S.5) Hallo Welt!? Programm Der Mensch (S.11) Klassen (S.12) Einführung Wie Funktioniert Code? Geschriebener
Elementare Mengenlehre
Vorkurs Mathematik, PD Dr. K. Halupczok WWU Münster Fachbereich Mathematik und Informatik 5.9.2013 Ÿ2 Elementare Mengenlehre Der grundlegendste Begri, mit dem Objekte und Strukturen der Mathematik (Zahlen,
Übersicht. Einführung in die Funktionale Programmierung: Einleitung & Motivation. Klassifizierung von Programmiersprachen (1)
Motivation Funktionale Programmiersprachen Haskell Übersicht Einführung in die Funktionale Programmierung: Einleitung & Motivation Prof Dr. Manfred Schmidt-Schauß 1 Motivation Übersicht Programmierparadigmen
Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny
Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny 9. Zeiger Arbeitsspeicher / Adressen Der Arbeitsspeicher des Computers (RAM) besteht aus einem Feld von Speicherzellen, beginnend bei Adresse
Kapitel 5: Abstrakte Algorithmen und Sprachkonzepte. Elementare Schritte
Elementare Schritte Ein elementarer Berechnungsschritt eines Algorithmus ändert im Allgemeinen den Wert von Variablen Zuweisungsoperation von fundamentaler Bedeutung Zuweisungsoperator In Pascal := In
Intuitionistische Lineare Logik
Lineare Logik Intuitionistische Lineare Logik Zusammenhang zur intuitionistischen Logik Termzuweisung und funktionale Interpretation Intuitionistische Lineare Logik Sinn und Zweck : Kontrolle über Ressourcen
Praktische Informatik 3: Einführung in die Funktionale Programmierung Vorlesung vom 10.11.2010: Rekursive Datentypen
Rev. 1152 1 [23] Praktische Informatik 3: Einführung in die Funktionale Programmierung Vorlesung vom 10.11.2010: Rekursive Datentypen Christoph Lüth & Dennis Walter Universität Bremen Wintersemester 2010/11
Funktionen höherer Ordnung
Eine Funktion wird als Funktion höherer Ordnung bezeichnet, wenn Funktionen als Argumente verwendet werden, oder wenn eine Funktion als Ergebnis zurück gegeben wird. Beispiel: twotimes :: ( a -> a ) ->
Programmierung WS12/13 Lösung - Übung 1 M. Brockschmidt, F. Emmes, C. Otto, T. Ströder
Prof. aa Dr. J. Giesl Programmierung WS12/13 M. Brockschmidt, F. Emmes, C. Otto, T. Ströder Tutoraufgabe 1 (Syntax und Semantik): 1. Was ist Syntax? Was ist Semantik? Erläutern Sie den Unterschied. 2.
Computeranwendung und Programmierung (CuP)
Computeranwendung und Programmierung (CuP) VO: Peter Auer (Informationstechnologie) UE: Norbert Seifter (Angewandet Mathematik) Organisatorisches (Vorlesung) Vorlesungszeiten Montag 11:15 12:45 Freitag
Der λ-kalkül. Frank Huch. Sommersemester 2015
Der λ-kalkül Frank Huch Sommersemester 2015 In diesem Skript werden die Grundlagen der Funktionalen Programmierung, insbesondere der λ-kalkül eingeführt. Der hier präsentierte Stoff stellt einen teil der
Schachtelung der 2. Variante (Bedingungs-Kaskade): if (B1) A1 else if (B2) A2 else if (B3) A3 else if (B4) A4 else A
2.4.6. Kontrollstrukturen if-anweisung: Bedingte Ausführung (Verzweigung) 2 Varianten: if (Bedingung) Anweisung (Anweisung = einzelne Anweisung oder Block) Bedeutung: die Anweisung wird nur ausgeführt,
Zahlen in Haskell Kapitel 3
Einführung in die Funktionale Programmiersprache Haskell Zahlen in Haskell Kapitel 3 FH Wedel IT-Seminar: WS 2003/04 Dozent: Prof. Dr. Schmidt Autor: Timo Wlecke (wi3309) Vortrag am: 04.11.2003 - Kapitel
Einführung in den Einsatz von Objekt-Orientierung mit C++ I
Einführung in den Einsatz von Objekt-Orientierung mit C++ I ADV-Seminar Leiter: Mag. Michael Hahsler Syntax von C++ Grundlagen Übersetzung Formale Syntaxüberprüfung Ausgabe/Eingabe Funktion main() Variablen
Lexikalische Programmanalyse der Scanner
Der Scanner führt die lexikalische Analyse des Programms durch Er sammelt (scanned) Zeichen für Zeichen und baut logisch zusammengehörige Zeichenketten (Tokens) aus diesen Zeichen Zur formalen Beschreibung
String s1, s2; Eine Zuweisung geschieht am einfachsten direkt durch Angabe des Strings eingeschlossen in doppelte Hochkommata:
Informatik mit Java: Gierhardt Zeichenketten bzw. Strings Der Datentyp String Zeichenketten bzw. Strings sind eine häufig benutzte Datenstruktur. Man könnte auch mit Arrays aus Zeichen arbeiten. Da aber
2 Polynome und rationale Funktionen
Gleichungen spielen auch in der Ingenieurmathematik eine große Rolle. Sie beschreiben zum Beispiel Bedingungen, unter denen Vorgänge ablaufen, Gleichgewichtszustände, Punktmengen. Gleichungen für eine
Kapitel 9. Komplexität von Algorithmen und Sortieralgorithmen
Kapitel 9 Komplexität von Algorithmen und Sortieralgorithmen Arrays 1 Ziele Komplexität von Algorithmen bestimmen können (in Bezug auf Laufzeit und auf Speicherplatzbedarf) Sortieralgorithmen kennenlernen:
Entwicklung eines korrekten Übersetzers
Entwicklung eines korrekten Übersetzers für eine funktionale Programmiersprache im Theorembeweiser Coq Thomas Strathmann 14.01.2011 Gliederung 1 Einleitung
EIGENSCHAFTEN VON SPRACHEN
Vorlesung und Übung Universität Paderborn Wintersemester 2016/2017 Dr. Peter Pfahler EIGENSCHAFTEN VON SPRACHEN EWS, WS 2016/17, Pfahler C-1 Einführung Sprachen in der Informatik werden für bestimmte Zwecke
2 Die Dimension eines Vektorraums
2 Die Dimension eines Vektorraums Sei V ein K Vektorraum und v 1,..., v r V. Definition: v V heißt Linearkombination der Vektoren v 1,..., v r falls es Elemente λ 1,..., λ r K gibt, so dass v = λ 1 v 1
Programmieren 2 Java Überblick
Programmieren 2 Java Überblick 1 Klassen und Objekte 2 Vererbung 4 Innere Klassen 5 Exceptions 6 Funktionsbibliothek 7 Datenstrukturen und Algorithmen 8 Ein-/Ausgabe 9 Graphische Benutzeroberflächen 10
