Haskell, Typen, und Typberechnung. Grundlagen der Programmierung 3 A. Überladung und Konversion in Haskell. Typisierung in Haskell

Ähnliche Dokumente
Grundprinzipien der funktionalen Programmierung

Funktionale Programmierung

Funktionale Programmierung mit Haskell. Jan Hermanns

Was bisher geschah. deklarative Programmierung. funktionale Programmierung (Haskell):

Funktionale Programmierung ALP I. Funktionen höherer Ordnung. Teil 2 SS Prof. Dr. Margarita Esponda. Prof. Dr.

Beispiele: (Funktionen auf Listen) (3) Bemerkungen: Die Datenstrukturen der Paare (2) Die Datenstrukturen der Paare

Definieren Sie eine Funktion circlearea zur Berechnung der Fläche eines Kreises mit gegebenen Radius (Float).

Übersicht. Einführung in die Funktionale Programmierung: Einleitung & Motivation. Klassifizierung von Programmiersprachen (1)

Verträge für die funktionale Programmierung Design und Implementierung

Haskell. A Wild Ride. Sven M. Hallberg. sm@khjk.org. 21C3 Berlin / Bildungswerk Hamburg p. 1/36

Eine zu Grunde liegende Typdefinition beschreibt eine Struktur, die alle erlaubten Instanzen dieses Typs gemeinsam haben.

Lösungvorschlag zum Übungsblatt 6: Software-Entwicklung I (WS 2007/08)

Formale Sprachen, reguläre und kontextfreie Grammatiken

Adressen. Praktikum Funktionale Programmierung Organisation und Überblick. Termine. Studienleistung

Grundlagen der Programmierung 2. Bäume

Funktionale Programmierung mit Haskell

Einführung in die funktionale Programmierung

Programmierung und Modellierung

Einführung in das Programmieren Prolog Sommersemester Teil 2: Arithmetik. Version 1.0

1 ÜBERSETZER. Compilerbau 1

Einfache Ausdrücke Datentypen Rekursive funktionale Sprache Franz Wotawa Institut für Softwaretechnologie

Programmiersprachen: rekursives Programmieren in Haskell

Haskell zur Constraint-Programmierung HaL8

Tutorium - Haskell in der Schule. Ralf Dorn - Dennis Buchmann - Felix Last - Carl Ambroselli

Modul 122 VBA Scribt.docx

Funktionale Programmierung Teil 2 Methodik: Spezifikation, Implementierung, Verifikation

Entwicklung eines korrekten Übersetzers

Proseminar: Perlen der Informatik II Haskell List comprehensions & Typklassen

Was bisher geschah Funktionale Programmierung in Haskell: Algebraische Datentypen Pattern Matching Polymorphie Typklassen Rekursive Datentypen:

Auswahl von Klauseln und Atomen in Prolog

Funktionale Programmierung

Eine Einführung in die funktionale Programmierung mit Haskell

Generische Record-Kombinatoren mit statischer Typprüfung

Funktionale Programmierung mit Haskell

Java Generics & Collections

Programmierung in Python

5.2 Das All-Pairs-Shortest-Paths-Problem (APSP-Problem) Kürzeste Wege zwischen allen Knoten. Eingabe: Gerichteter Graph G =(V, E, c)

ALP I. Funktionale Programmierung

1 Polymorphie (Vielgestaltigkeit)

"Alles, was einen Wert zurueckliefert, ist ein Ausdruck." Konstanten, Variablen, "Formeln" oder auch Methoden koennen Werte zurueckgeben.

Informatik Repetitorium SS Volker Jaedicke

Funktionale Programmierung mit Haskell

Codes und Informationsgehalt

Wissensbasierte Systeme

Deklarationen in C. Prof. Dr. Margarita Esponda

Funktionale Programmierung. der direkte Weg vom Modell zum Programm

Funktionale Programmierung. Frank Adler

Programmiertechnik II

Ein erstes Java-Programm

1. Probeklausur zu Programmierung 1 (WS 07/08)

Gliederung. Tutorium zur Vorlesung. Gliederung. Gliederung. 1. Gliederung der Informatik. 1. Gliederung der Informatik. 1. Gliederung der Informatik

Proseminar Funktionales Programmieren. Stephan Kreutzer

Funktionale Programmierung mit Haskell

Praktische Informatik 3: Einführung in die Funktionale Programmierung Vorlesung vom : Rekursive Datentypen

Funktionales Programmieren in Python

Propädeutikum. Dipl.-Inf. Frank Güttler

Ausarbeitung des Interpreter Referats

Heutiges Thema... Datenstrukturen in Haskell... Algebraische Datentypen (data Tree =...) Typsynonyme (type Student =...)

Fragen. f [ ] = [ ] f (x : y : ys) = x y : f ys f (x : xs) = f (x : x : xs) Wozu evaluiert f [1, 2, 3] (Abkürzung für f (1 : 2 : 3 : [ ]))?

Fakultät Wirtschaftswissenschaft

Tutoraufgabe 1 (Datenstrukturen in Haskell):

Sprachbeschreibung und Erweiterung

Kapitel 3: Programmierung mit Kombinatoren

Grundlagen der Informatik. Prof. Dr. Stefan Enderle NTA Isny

2: Zahlentheorie / Restklassen 2.1: Modulare Arithmetik

Funktionale Programmierung

Terme stehen für Namen von Objekten des Diskursbereichs (Subjekte, Objekte des natürlichsprachlichen Satzes)

Programmieren in Haskell

Kapitel 7: Benutzerdefinierte Datentypen

Grundlagen der Programmierung 2. Parallele Verarbeitung

Binärbäume als weiteres Beispiel für abstrakte Datentypen in PVS mit in Knoten gespeicherten Werten vom Typ T:

C allgemein. C wurde unter und für Unix entwickelt. Vorläufer sind BCPL und B.

Einführung Datentypen Verzweigung Schleifen Funktionen Dynamische Datenstrukturen. Java Crashkurs. Kim-Manuel Klein

Spracherweiterungen von C# 3.5

7down Zusatzaufgaben. Mathias Ziebarth und Joachim Breitner. 13. März 2008

Syntaktische Analyse (Parsen)

Grundlagen der Programmierung Prof. H. Mössenböck. 3. Verzweigungen

TECHNISCHE UNIVERSITÄT MÜNCHEN FAKULTÄT FÜR INFORMATIK

Einführung in die Informatik Grammars & Parsers

Modellierung und Programmierung

Propädeutikum zur Programmierung

Programmierung 1 (Wintersemester 2012/13) Lösungsblatt 11 (Kapitel 12)

Kapitel 6. Komplexität von Algorithmen. Xiaoyi Jiang Informatik I Grundlagen der Programmierung

Haskell, eine rein funktionale Programmiersprache

Übungen zur Vorlesung Funktionale Programmierung. Wintersemester 2012/2013 Übungsblatt 1

SOI Die Schweizer Informatikolympiade

Grundlagen und Basisalgorithmus

Übersicht. Schleifen. Schleifeninvarianten. Referenztypen, Wrapperklassen und API. 9. November 2009 CoMa I WS 08/09 1/15

Übungsblatt 3: Algorithmen in Java & Grammatiken

Jürgen Bayer. Anonyme Methoden, Lambda-Ausdrücke und Ausdrucksbäume in.net

Java 7. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Dezember 2011 JAV7

Kapitel 12: Übersetzung objektorienter Konzepte

Kapitel 11: Wiederholung und Zusammenfassung

L6. Operatoren und Ausdrücke

Klausur in Programmieren

Kontrollstrukturen, Pseudocode und Modulo-Rechnung

Objektorientiertes Programmieren für Ingenieure

Programmieren in C. Macros, Funktionen und modulare Programmstruktur. Prof. Dr. Nikolaus Wulff

Java Einführung VARIABLEN und DATENTYPEN Kapitel 2

Praktikum BKSPP. Aufgabenblatt Nr Umrechnung zwischen Stellenwertsystemen

Transkript:

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 2014 Milners Typcheck Grundlagen der Programmierung 2 (Typen-A) 2/35 Typisierung in Haskell Überladung und Konversion in Haskell Haskell hat eine starke, statische Typisierung. mit parametrisch polymorphen Typen. jeder Ausdruck muss einen Typ haben Der Typchecker berechnet Typen aller Ausdrücke und prüft Typen zur Compilezeit Es gibt keine Typfehler zur Laufzeit d.h. kein dynamischer Typcheck nötig. Haskell: keine Typkonversion Es gibt Überladung: z.b. arithmetische Operatoren: +,., / ganze Zahlkonstanten sind überladen Grundlagen der Programmierung 2 (Typen-A) 3/35 Grundlagen der Programmierung 2 (Typen-A) 4/35

Typisierung, Begriffe Syntax von Typen in Haskell (ohne Typklassen) polymorph: parametrisch polymorph: Beispiel Schema: Ein Ausdruck kann viele Typen haben (vielgestaltig, polymorph). Die (i.a. unendliche) Menge der Typen entspricht einem schematischen Typausdruck [a]->int Typ ::= Basistyp ( Typ ) Typvariable Typkonstruktor n { Typ } n (n = Stelligkeit) Basistyp ::= Int Integer Float Rational Char Instanzen: [Int]->Int, [Char]->Int, [[Char]]->Int Grundlagen der Programmierung 2 (Typen-A) 5/35 Grundlagen der Programmierung 2 (Typen-A) 6/35 Syntax von Typen Interpretation der Typen Typkonstruktoren können benutzerdefiniert sein (z.b. Baum a) Vordefinierte Liste [ ] Typkonstruktoren: Tupel (.,...,.) Funktionen (Stelligkeit 2, Infix) Konvention zu Funktionstypen mit a b c d bedeutet: a (b (c d)). length :: [a] -> Interpretation: Int Für alle Typen typ ist length eine Funktion, die vom Typ [typ] Int ist. Grundlagen der Programmierung 2 (Typen-A) 7/35 Grundlagen der Programmierung 2 (Typen-A) 8/35

Komposition Typ der Komposition Beispiel: Komposition von Funktionen: komp::(a -> b) -> (c -> a) -> c -> b komp f g x = f (g x) In Haskell ist komp vordefiniert und wird als. geschrieben: Beispielaufruf: *Main> suche_nullstelle (sin. quadrat) 1 4 0.00000001 1.772453852929175 (sin. quadrat) entspricht sin(x 2 ) und quadrat. sin entspricht (sin(x)) 2. Erklärung zum Typ von komp, wobei {a,b,c} Typvariablen sind. Ausdruck: f komp g bzw. f. g (a->b) -> (c->a) -> c->b Typ von (.) (τ 1 -> τ 2 ) Typ von f (τ 3 -> τ 1 ) Typ von g τ 3 Typ des Arguments x der Komposition f. g τ 2 Typ des Resultats der Komposition f(g x) (τ 3 -> τ 2 ) Typ von (f. g) x :: τ 3 g τ 1 f τ 2 Grundlagen der Programmierung 2 (Typen-A) 9/35 Grundlagen der Programmierung 2 (Typen-A) 10/35 Typregeln Typregel Anwendung : mehrere Argumente Wie berechnet man Typen von Ausdrücken? Anwendung von Funktionsausdruck auf Argument s :: σ τ, t :: σ (s t) ::? Beispiele: quadrat :: Int Int, 2 :: Int (quadrat 2) ::? + :: Int (Int Int), 1 :: Int (1 +) ::?, 2:: Int ((1 +) 2) ::? Beispiele s :: σ 1 σ 2... σ n τ, t 1 :: σ 1,..., t n :: σ n (s t 1... t n ) :: τ + :: Int Int Int, 1 :: Int, 2 :: Int (+ 1 2) :: Int + :: Int Int Int (1 + 2) :: Int Grundlagen der Programmierung 2 (Typen-A) 11/35 Grundlagen der Programmierung 2 (Typen-A) 12/35

Beispiel Anwendungsregel für polymorphe Typen even::int -> Bool (.)::(a -> b) -> (c -> a) -> c -> b quadrat::int -> Int a -> b. = Int -> Bool c -> b. = Int -> Bool c -> a. = Int -> Int Ziel: Anwendung der Typregel für z.b. length oder map Neuer Begriff: γ ist eine Typsubstitution wenn sie Typen für Typvariablen einsetzt γ(τ) nennt man Instanz von τ even. quadrat :: Int -> Bool Beispiel Typsubstitution: Instanz: γ = {a Char, b Float} γ([a] Int) = [Char] Int Grundlagen der Programmierung 2 (Typen-A) 13/35 Grundlagen der Programmierung 2 (Typen-A) 14/35 Anwendungsregel für polymorphe Typen Beispiel zur polymorphen Anwendungsregel Typ von (map quadrat)? s :: σ τ, t :: ρ und γ(σ) = γ(ρ) (s t) :: γ(τ) Berechnet den Typ von (s t) wenn Typen von s, t schon bekannt sind Hierbei ist zu beachten: die Typvariablen in ρ müssen vorher umbenannt werden, so dass σ und ρ keine gemeinsamen Typvariablen haben. map :: (a b) ([a] [b]) Instanziiere mit: γ = {a Int, b Int} ergibt: map :: (Int Int) ([Int] [Int]) Regelanwendung ergibt: map :: (Int Int) ([Int] [Int]), quadrat :: (Int Int) (map quadrat) :: [Int] [Int] Grundlagen der Programmierung 2 (Typen-A) 15/35 Grundlagen der Programmierung 2 (Typen-A) 16/35

Polymorphe Regel für n Argumente Wie berechnet man die Typsubstitutionen? s :: σ 1 σ 2... σ n τ, t 1 :: ρ 1,..., t n :: ρ n und i : γ(σ i ) = γ(ρ i ) (s t 1... t n ) :: γ(τ) Unifikation: Berechnung der allgemeinsten Typsubstitution im Typberechnungsprogramm bzw Typchecker Die Typvariablen in ρ 1,..., ρ n müssen vorher umbenannt werden. Unifikation wird benutzt im Typchecker von Haskell! Beachte: verwende möglichst allgemeines γ (kann berechnet werden; s.u.) Grundlagen der Programmierung 2 (Typen-A) 17/35 Grundlagen der Programmierung 2 (Typen-A) 18/35 polymorphe Typen; Unifikation Unifikation: Regelbasierter Algorithmus Man braucht 4 Regeln, die auf (E; G) operieren: s :: σ τ, t :: ρ und γ ist allgemeinster Unifikator von σ. = ρ (s t) :: γ(τ) Hierbei ist zu beachten: die Typvariablen in ρ müssen vorher umbenannt werden. E: Menge von Typgleichungen, G: Lösung; mit Komponenten der Form x t. Beachte; x sind Typvariablen, t sind Typen, f, g sind Typkonstruktoren Grundlagen der Programmierung 2 (Typen-A) 19/35 Grundlagen der Programmierung 2 (Typen-A) 20/35

Unifikation: Die Regeln Unifikation: Regelbasierter Algorithmus Start mit G = ; E G; {x. = x} E G; E G; {t. = x} E G; {x. = t} E G; {x =. t} E G[t/x] {x t}; E[t/x] Wenn t keine Variable ist G; {(f s 1... s n ). = (f t 1... t n )} E G; {s 1. = t1,..., s n. = tn )} E Wenn x nicht in t Fehlerabbruch, wenn: x =. t in E, x t und x kommt in t vor. (f(...) =. g(...) kommt in E vor und f g. Fehlerabbruch bedeutet: nicht typisierbar Ersetzung: Effekt: E[t/x]: alle Vorkommen von x werden durch t ersetzt G[t/x]: jedes y s wird durch y s[t/x] ersetzt Grundlagen der Programmierung 2 (Typen-A) 21/35 Grundlagen der Programmierung 2 (Typen-A) 22/35 Beispiel mit Typvariablen Beispiel mit Typvariablen Berechne Typ von (map id) map:: (a b) [a] [b] id:: a a Regelanwendung benötigt Lösung von (a b). = (a a ): G E ; {(a b) =. (a a )} ; {a =. a, b =. a } {a a }; {b =. a } {a a, b a }; {a a, b a }; map :: (a b) ([a] [b]), id :: a a (map id) :: γ([a] [b]) Einsetzung der Lösung γ = {a a, b a } ergibt (map id) :: ([a ] [a ]). Grundlagen der Programmierung 2 (Typen-A) 23/35 Grundlagen der Programmierung 2 (Typen-A) 24/35

Beispiel (foldr (:) []) ::?? foldr :: (a -> b -> b) -> b -> [a] -> b (:) :: a -> [a] -> [a] ([]) :: [a] G E {a b b =. c [c] [c], b =. [d]} {b [d]} {a [d] [d] =. c [c] [c]} {b [d]} {a =. c, [d] =. [c], [d] =. [c]} {b [d], a c} {[d] =. [c], [d] =. [c]} {b [d], a c} {d =. c, [d] =. [c]} {b [c], a c, d c} {[c] =. [c]} {b [c], a c, d c} {c =. c} {b [c], a c, d c} {} (foldr (:) [])::[c] [c] = γ([a] b) Beispiel. Linksfaltung: (foldl (:) [])? foldl :: (a -> b -> a) -> a -> [b] -> a (:) :: a -> [a] -> [a] ([]) :: [a] G E {a b a) =. c [c] [c], a =. [d]} {a [d]} {[d] b [d] =. c [c] [c]} {a [d]} {[d] =. c, b =. [c], [d] =. [c]} {a [d], b [c]} {[d] =. c, [d] =. [c]} {a [d], b [c]} {c =. [d], [d] =. [c]} {a [d], b [[d]], c [d]} {[d] =. [[d]]} {a [d], b [[d]], c [d]} {d =. [d]} nicht lösbar Grundlagen der Programmierung 2 (Typen-A) 25/35 Grundlagen der Programmierung 2 (Typen-A) 26/35 Beispiel zu Typberechnung Beispiele zu polymorpher Typberechnung Typ von map length map :: (a b) ([a] [b]), length :: [a ] Int (map length) ::? Unifiziere (a b). = [a ] Int G E ; {(a b) =. ([a ] Int)} ; {a =. [a ], b =. Int} {a [a ]}; {b =. Int} {a [a ], b Int}; Berechne Typ der Liste [1]: 1 : Int (:) :: a [a] [a] [] :: [b] 1 : [] ::? Anwendungsregel ergibt Gleichungen: {a. = Int, [a]. = [b]} Lösung: γ = {a Int} Typ (1 : []) :: [Int] Somit: (map length) :: γ([a] [b]) = [[a ]] [Int] Grundlagen der Programmierung 2 (Typen-A) 27/35 Grundlagen der Programmierung 2 (Typen-A) 28/35

Beispiel zu Typfehler Beispiel zu Typfehler im Interpreter [1, a ] hat keinen Typ: 1 : ( a : []) 1 :: Integer, [] :: [b], a :: Char (Typen der Konstanten.) (1 :) :: [Integer] [Integer] und ( a :[]) :: [Char]. Kein Typ als Resultat, denn: [Integer]. = [Char] ist nicht lösbar. 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 ] Grundlagen der Programmierung 2 (Typen-A) 29/35 Grundlagen der Programmierung 2 (Typen-A) 30/35 Typ eines Ausdrucks Typisierung von Funktionen und Ausdrücken Typ von (map quadrat [1,2,3,4]) : map:: (a b) [a] [b] quadrat:: Integer Integer, und [1, 2, 3, 4] :: [Integer]. γ = {a Integer, b Integer}. Das ergibt: γ(a) = Integer, γ([a]) = [Integer], γ([b]) = [Integer]. Resultat: γ([b]) = [Integer] Problematik: rekursiv definierte Funktionen Lambda-Ausdrücke, let-ausdrücke Listen-Komprehensionen. Typcheckalgorithmus von Robin Milner (in Haskell und ML) ist schnell, liefert allgemeinste (Milner-)Typen benutzt Unifikation (eine optimierte Variante) schlechte worst-case Komplexität: in seltenen Fällen exponentieller Zeitbedarf Liefert in seltenen Fällen nicht die allgemeinsten möglichen polymorphen Typen Grundlagen der Programmierung 2 (Typen-A) 31/35 Grundlagen der Programmierung 2 (Typen-A) 32/35

Typisierung von Funktionen, Milner Typisierung und Reduktion Satz zur Milner-Typisierung in Haskell: Sei t ein getypter Haskell-Ausdruck, ohne freie Variablen. Dann wird die Auswertung des Ausdrucks t nicht mit einem Typfehler abbrechen. Beachte: Nach Reduktionen kann ein Ausdruck mehr Typen (bzw. einen allgemeineren Typ) haben als vor der Reduktion Beispiel: if 1 > 0 then [] else [1] :: [Integer] Allgemeine Aussage zu starken Typsystemen Es gibt keine dynamischen Typfehler, wenn das Programm statisch korrekt getypt ist arithmetische-reduktion: if True then [] else [1] Case-Reduktion: [] :: [Integer] :: [a] Grundlagen der Programmierung 2 (Typen-A) 33/35 Grundlagen der Programmierung 2 (Typen-A) 34/35 Typisierung und Reduktion weiteres Beispiel: (if 1 > 0 then foldr else foldl) :: (a -> a -> a) -> a -> [a] -> a Reduktion ergibt als Resultat: foldr:: (a -> b -> b) -> b -> [a] -> b der Typ ist allgemeiner geworden! Grundlagen der Programmierung 2 (Typen-A) 35/35