Haskell, Typen und Typberechnung
|
|
|
- Lena Voss
- vor 8 Jahren
- Abrufe
Transkript
1 Kapitel 3 Haskell, Typen und Typberechnung 3.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 2 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 3 (:) :: 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 4 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. Der Algorithmus operiert auf einem Paar aus einer Lösung G und einer Multimenge E von Gleichungen. T C bezeichnet Typkonstruktoren, a eine
5 5 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] {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ösungskomponenten 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 Wenn σ keine Typvariable ist. 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. Wenn E nicht leer ist, aber keine Regel anwendbar, dann ist das Verfahren nicht erfolgreich und es wird keine Lösung gefunden. Es gibt auch Regeln, die direkt anzeigen, dass die Gleichungen nicht lösbar sind: Es gibt keine Lösung, wenn: x. = t in E, x t und x kommt in t vor. (f...). = (g...) kommt in E vor und f g. Die Korrektheit des Verfahrens wollen wir hier nicht zeigen, aber es ist offensichtlich, dass die so berechnete Substitution das letzte Gleichungssystem erfüllt. Die Regel für die Anwendung mit Unifikation ist:
6 6 s : σ τ, t : ρ und γ(σ) = γ(ρ) (s t) :: γ(τ) wenn γ allgemeinster Unifikator von σ. = ρ ist, wobei die Typvariablen in ρ umbenannt sind Beispiel Bei der Typisierung für (map id) zeigt sich, dass man unterschiedliche Typsubstitutionen finden kann: Die eigentliche Typisierung ist: Berechnen von γ: map :: (a b) [a] [b], id :: a a (map id) :: γ([a] [b]) 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 ).
7 7 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] 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. Prelude> [1, a ] <interactive>:1:1: No instance for (Num Char) arising from the literal 1 at <interactive>:1:1 Possible fix: add an instance declaration for (Num Char) In the expression: 1 In the expression: [1, a ] In the definition of it : it = [1, a ] 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].
8 8 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 Zeitbedarf. 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. 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,
9 9 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. 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. Python ist objektorientiert und hat ein Klassensystem. Damit kann man Klassen als Typen verwenden, was aber nicht zu einem starken, sondern zu einem dynamisch Typsystem führt. Man könnte vermutlich ein monomorphes Typsystem zu Python hinzufügen. Python hat aber keine syntaktischen Elemente, um den Typ einer Variablen festzulegen; und 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
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
Haskell, Typen und Typberechnung
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
Haskell, Typen, und Objektorientierung
Haskell, Typen, und Objektorientierung ZIELE dieses Kapitels Haskells Typisierung Milners Polymorpher Typcheck Haskells Typklassen P raktische Informatik 2, SS 2005, F olien Kap.3, (27. Mai2005) Seite
Haskell, Typen, und Typberechnung. Grundlagen der Programmierung 3 A. Überladung und Konversion in Haskell. 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 Sommersemester
Grundlagen der Programmierung 3 A
Grundlagen der Programmierung 3 A Typen, Typberechnung und Typcheck Prof. Dr. Manfred Schmidt-Schauß Sommersemester 2017 Haskell, Typen, und Typberechnung Ziele: Haskells Typisierung Typisierungs-Regeln
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
Grundlagen der Programmierung 2 (1.A)
Grundlagen der Programmierung 2 (1.A) Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie 18. April 2007 Grundlagen der Programmierung 2: Geplanter Inhalt der ersten Hälfte
Einführung in die funktionale Programmierung
Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie 26. Oktober 2006 Haskell - Einführung Syntax Typen Auswertung Programmierung
Übersicht. Einführung in die Funktionale Programmierung: Ziele des Kapitels. Typisierung Prof Dr. Manfred Schmidt-Schauß WS 2012/13
Übersicht Einführung in die Funktionale Programmierung: Typisierung Prof Dr. Manfred Schmidt-Schauß WS 2012/13 1 Motivation 2 Typen: Sprechweisen, Notationen und Unifikation 3 Typisierungsverfahren Iteratives
Einführung in die funktionale Programmierung
Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie 17. Oktober 2006 Einführung in Haskell: Syntax, Reduktionen, Kernsprachen Haskell,
Grundlagen der Programmierung 2. Operationale Semantik
Grundlagen der Programmierung 2 Operationale Semantik Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie 29. April 2009 Semantik von Programmiersprachen Semantik = Bedeutung
Grundlegende Datentypen
Funktionale Programmierung Grundlegende Datentypen Fakultät für Informatik und Mathematik Hochschule München Letzte Änderung: 14.11.2017 15:37 Inhaltsverzeichnis Typen........................................
Funktionale Programmierung Grundlegende Datentypen
Grundlegende Datentypen Prof. Dr. Oliver Braun Fakultät für Informatik und Mathematik Hochschule München Letzte Änderung: 06.11.2017 16:45 Inhaltsverzeichnis Typen........................................
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
Programmiersprachen: Klassifizierung und Methoden. Programmier-Paradigmen. Grundlagen der Programmierung 2 (1.C) - 1 -
Programmiersprachen: Klassifizierung und Methoden Programmier-Paradigmen Grundlagen der Programmierung 2 (1.C) - 1 - Programmiersprachen: Begriffe Syntax Beschreibung der Programme als Texte let xyz =
Operationale Semantik: Haskell
Kapitel 4 Operationale Semantik: Haskell 4.1 Semantik von Programmiersprachen Programme sind zunächst mal nur Text. Programme sollen aber etwas im Rechner bewirken bzw. eine Funktion oder Funktionalität
Die 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
Kapitel 6: Typprüfung
Ludwig Maximilians Universität München Institut für Informatik Lehr- und Forschungseinheit für Datenbanksysteme Skript zur Vorlesung Informatik I Wintersemester 2006 Vorlesung: Prof. Dr. Christian Böhm
Einführung in die funktionale Programmierung
Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie 28. Oktober 2008 Einführung in Haskell: Syntax, Reduktionen, Kernsprachen Haskell,
Der einfach getypter Lambda-Kalkül
Der einfach getypter Lambda-Kalkül Typprüfung und Typinferenz Tobias Nipkow und Steffen Smolka Technische Universität München 1 Einleitung 2 Explizit getypter λ-kalkül 3 Implizit getypter λ-kalkül Statische
Grundlagen der Programmierung 2 (1.A)
Grundlagen der Programmierung 2 (1.A) Einführung Prof. Dr. Manfred Schmidt-Schauß Sommersemester 2017 Grundlagen der Programmierung 2 Geplanter Inhalt der ersten Hälfte: Programmieren in Haskell Definitionen;
Abschnitt 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
Grundlagen der Programmierung 2 (1.A)
Grundlagen der Programmierung 2 (1.A) Einführung Prof. Dr. Manfred Schmidt-Schauß Sommersemester 2015 Grundlagen der Programmierung 2 Geplanter Inhalt der ersten Hälfte: Programmieren in Haskell Definitionen;
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
Beweise und Typen. 9.1 Formalisierung und Beweis
120 9. Beweise und Typen 9 Beweise und Typen Dieses Kapitel ist zweigeteilt. Als erstes wenden wir uns dem Thema zu, wie wir Eigenschaften von funktionalen Programmen beweisen können. Aufwandsabschätzungen
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 =
Grundlagen der Programmierung 2 (1.A)
Grundlagen der Programmierung 2 (1.A) Einführung Prof. Dr. Manfred Schmidt-Schauß Sommersemester 2018 Grundlagen der Programmierung 2 Geplanter Inhalt der ersten Hälfte: Programmieren in Haskell Definitionen;
5.3 Auswertung von Ausdrücken
5.3 Auswertung von Ausdrücken Funktionen in Java bekommen Parameter/Argumente als Input, und liefern als Output den Wert eines vorbestimmten Typs. Zum Beispiel könnte man eine Funktion i n t min ( i n
n 1. Der Begriff Informatik n 2. Syntax und Semantik von Programmiersprachen - 1 -
n 1. Der Begriff Informatik n 2. Syntax und Semantik von Programmiersprachen I.2. I.2. Grundlagen von von Programmiersprachen. - 1 - 1. Der Begriff Informatik n "Informatik" = Kunstwort aus Information
Einleitung Typsystem Typisierung Zusammenfassung Literatur. Typisierung. Effiziente Programmierung. Thomas Schnieders
Typisierung Effiziente Programmierung Thomas Schnieders Fachbereich Informatik Fakultät für Mathematik, Informatik und Naturwissenschaften Universität Hamburg 2018-04-26 Thomas Schnieders Typisierung 1
1. Typen 1.1 Typsicherheit 1.2 Typprüfung
1. Typen 1.1 Typsicherheit 1.2 Typprüfung Ein Typsystem ist ein praktikables, syntaktisches Verfahren, mit dem man die Abwesenheit gewisser Laufzeit-Eigenschaften eines Programms beweisen kann, indem man
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
Basiskonstrukte 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
Programmieren in Haskell Das Haskell Typsystem
Programmieren in Haskell Das Haskell Typsystem Peter Steffen Robert Giegerich Universität Bielefeld Technische Fakultät 22.01.2010 1 Programmieren in Haskell Belauscht... Lisa Lista: Ohne Typen keine korrekten
3. Java - Sprachkonstrukte I
Namen und Bezeichner Ein Programm (also Klasse) braucht einen Namen 3. Java - Sprachkonstrukte I Namen und Bezeichner, Variablen, Zuweisungen, Konstanten, Datentypen, Operationen, Auswerten von Ausdrücken,
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
3. Java - Sprachkonstrukte I
84 3. Java - Sprachkonstrukte I Namen und Bezeichner, Variablen, Zuweisungen, Konstanten, Datentypen, Operationen, Auswerten von Ausdrücken, Typkonversionen Namen und Bezeichner 85 Ein Programm (also Klasse)
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
3. Java - Sprachkonstrukte I
Lernziele 3. Java - Sprachkonstrukte I Namen und Bezeichner, Variablen, Zuweisungen, Konstanten, Datentypen, Operationen, Auswerten von Ausdrücken, Typkonversionen Sie kennen die grundlegensten Bausteine
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
III.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
Funktionale 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
Objektorientierte Programmierung. Kapitel 3: Syntaxdiagramme
Stefan Brass: OOP (Java), 3. 1/31 Objektorientierte Programmierung Kapitel 3: Stefan Brass Martin-Luther-Universität Halle-Wittenberg Wintersemester 2014/15 http://www.informatik.uni-halle.de/ brass/oop14/
Funktionale Programmierung ALP I. Funktionen höherer Ordnung SS Prof. Dr. Margarita Esponda. Prof. Dr. Margarita Esponda
ALP I SS 2011 Funktionstypen Funktionen haben einen Datentyp, der folgende allgemeine Form hat: functionname :: T 1 -> T 2, wobei T 1, T 2 wiederum beliebige Datentypen sind Beispiel: T 1 T 2 Der Datentyp
Die Prädikatenlogik erster Stufe: Syntax und Semantik
Die Prädikatenlogik erster Stufe: Syntax und Semantik 1 Mathematische Strukturen und deren Typen Definition 1.1 Eine Struktur A ist ein 4-Tupel A = (A; (R A i i I); (f A j j J); (c A k k K)) wobei I, J,
Haskell und Python. pures Programmieren, Auswerten von Ausdrücken rekursives Programmieren, Typsystem. Python: Eine prozedurale Programmiersprache
Haskell und Python Haskell: Eine funktionale Programmiersprache funktional, nicht-strikt, hat ein polymorphes und starkes Typsystem, flexible Datenstrukturen, gute Abstraktionseigenschaften, Ziele: pures
Kapitel 2: Ausdrücke. 1. Sorten und abstrakte Datentypen. 2. Ausdrücke 2.1 Syntax 2.2 Semantik 2.3 Ausdrücke in Java. 3. Funktionale Algorithmen
Kapitel 2: Ausdrücke 1. Sorten und abstrakte Datentypen 2. Ausdrücke 2.1 Syntax 2.2 Semantik 2.3 Ausdrücke in Java 3. Funktionale Algorithmen 4. Variablen, Anweisungen, Prozeduren 5. Prozeduraufrufe 54
Grundelemente objektorientierter Sprachen (1)
Grundelemente objektorientierter Sprachen (1) Objekt Repräsentation eines Objektes der realen Welt in der Terminologie objektorientierter Programmiersprachen besitzen Attribute (Eigenschaften), deren Werte
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
ProInformatik: 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
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
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
Programmieren in Haskell Einführung
Programmieren in Haskell Einführung Peter Steffen Universität Bielefeld Technische Fakultät 17.10.2008 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 - 1 -
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
1. Der Begriff Informatik 2. Syntax und Semantik von Programmiersprachen - 1 -
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
Stackmaschine; Speicheradressierung
Stackmaschine; Speicheradressierung Erweiterung um globalen Speicher (Heap, Halde) pro Speicherplatz eine Zahl. Notation ist als Array SP [0..]. Zugriff mittels Adresse (Index): eine Zahl i.a.: Zahlen
Projekt 3 Variablen und Operatoren
Projekt 3 Variablen und Operatoren Praktisch jedes Programm verarbeitet Daten. Um mit Daten programmieren zu können, muss es Möglichkeiten geben, die Daten in einem Programm zu verwalten und zu manipulieren.
Vorsemesterkurs Informatik Sommersemester Aufgabenblatt Nr. 5A. Lösung zu Aufgabe 1 (Fehler in Haskell-Quelltext: Parsefehler)
Fachbereich Informatik und Mathematik Institut für Informatik Vorsemesterkurs Informatik Sommersemester 2017 Aufgabenblatt Nr. 5A zu Aufgabe 1 (Fehler in Haskell-Quelltext: Parsefehler) Laden Sie von der
