Programmieren in Haskell



Ähnliche Dokumente
Programmieren in Haskell

Programmieren in Haskell Felder (Arrays)

Programmieren in Haskell Felder

ALP I. Funktionale Programmierung

Funktionale Programmierung mit Haskell

Programmieren in Haskell

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

Funktionale Programmierung mit Haskell

Programmieren in Haskell Programmiermethodik

Programmieren in Haskell

Kapitel 6: Abstraktion. Programmieren in Haskell 1

Programmieren in Haskell Einstieg in Haskell

Algorithmen und Programmieren 1 Funktionale Programmierung - Musterlösung zur Übungsklausur -

Funktionale Programmierung. ALP I Lambda-Kalkül. Teil IVb WS 2012/2013. Prof. Dr. Margarita Esponda. Prof. Dr. Margarita Esponda

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

Objektorientierte Programmierung

Programmieren in Haskell Einführung

Klausur in Programmieren

Programmierkurs II. Typsynonyme & algebraische Datentypen

Paradigmen der Programmierung

Kapitel 3: Eine einfache Programmiersprache. Programmieren in Haskell 1

Funktionale Programmierung ALP I. Algebraische Datentypen und Abstrakte Datentypen. SS 2013 Prof. Dr. Margarita Esponda. Prof. Dr.

Typdeklarationen. Es gibt in Haskell bereits primitive Typen:

Scala kann auch faul sein

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

Modul 122 VBA Scribt.docx

Einführung in die funktionale Programmierung

Programmieren in Haskell Abstrakte Datentypen

Ich liebe Java && Ich liebe C# Rolf Borst

Typklassen. Natascha Widder

Client-Server-Beziehungen

Programmieren in Haskell

Grundlegende Datentypen

Funktionale Programmierung Grundlegende Datentypen

Programmierung I Einführung in Python, Beyond the Basics

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

Wiederholung ADT Menge Ziel: Verwaltung (Finden, Einfügen, Entfernen) einer Menge von Elementen

Klausur in Programmieren

Programmieren in Haskell. Abstrakte Datentypen

Modellierung und Programmierung 1

Institut für Programmierung und Reaktive Systeme 25. August Programmier-Labor Übungsblatt. int binarysearch(int[] a, int x),

1 - FortProg ist: [ ] objekt-orientiert; [ ] funktional; [ ] logisch; [ ] manchmal nicht auszuhalten

Programmieren in Haskell

Programmieren in Haskell

Grundlagen der Programmierung Prof. H. Mössenböck. 14. Schrittweise Verfeinerung

[10] Software Transactional Memory in Haskell, Tortenwurf und Aufgabenblatt 7

Programmieren in Haskell Das Haskell Typsystem

Wir machen neue Politik für Baden-Württemberg

Einführung in die Programmierung

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

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

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

Kapitel 8: Physischer Datenbankentwurf

Funktionale Programmierung. ALP I Lambda-Kalkül. Teil III SS Prof. Dr. Margarita Esponda. Prof. Dr. Margarita Esponda

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

Einführung in Haskell

Einfache Arrays. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Monoide. Funktionale Programmierung. Prof. Dr. Oliver Braun Letzte Änderung: :54. Monoide 1/16

Im Jahr t = 0 hat eine Stadt Einwohner. Nach 15 Jahren hat sich die Einwohnerzahl verdoppelt. z(t) = at + b

Funktionale Programmierung

SMS_01.lib. Inhalt. WAGO-I/O-PRO 32 Bibliothek

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

Grundlagen von Python

In vergleichsbasierten Suchbäumen wird nicht in Schlüssel hineingeschaut.

Einrichten einer mehrsprachigen Webseite mit Joomla (3.3.6)

Prüfung Funktionale Programmierung

Funktionale Programmierung. Monoide. Prof. Dr. Oliver Braun. Fakultät für Informatik und Mathematik Hochschule München

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

DataTables LDAP Service usage Guide

Java Einführung Collections

Konfigurationsanleitung Access Control Lists (ACL) Funkwerk. Copyright Stefan Dahler Oktober 2008 Version 1.0.

SEMINAR Modifikation für die Nutzung des Community Builders

1. Schritt: Export Datei im Fidelio erstellen

Hochschule Darmstadt Informatik-Praktikum (INF 1) WS 2015/2016 Wirtschaftsingenieur Bachelor 5. Aufgabe Datenstruktur, Dateieingabe und -ausgabe

WS 2011/2012. Georg Sauthoff 1. October 18, 2011

Informatik Grundlagen, WS04, Seminar 13

Graphic Coding. Klausur. 9. Februar Kurs A

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

Praktische Informatik 3: Funktionale Programmierung Vorlesung 4 vom : Typvariablen und Polymorphie

Java Kurs für Anfänger Einheit 4 Klassen und Objekte

Nachweis der Verhaltensäquivalenz von Feldbus-Komponenten auf unterschiedlichen Abstraktionsebenen

Motivation. Formale Grundlagen der Informatik 1 Kapitel 5 Kontextfreie Sprachen. Informales Beispiel. Informales Beispiel.

Transkript:

Programmieren in Haskell Felder (Arrays) Programmieren in Haskell 1

Was wir heute machen Motivationsbeispiel Die Typklasse Ix Felder in Haskell Funktionstabellierung Binäre Suche Pascalsches Dreieck Ein lineares Sortierverfahren Hashing (ansprochsvolles Projekt) Programmieren in Haskell 2

Quadratzahlen 0 1 2 3 n 0 1 4 9 n 2 Programmieren in Haskell 3

Quadratzahlen 0 1 2 3 n 0 1 4 9 n 2 squareslist :: Integral a => [a] squareslist = [n^2 n <- [0..]] Programmieren in Haskell 3

Quadratzahlen 0 1 2 3 n 0 1 4 9 n 2 squareslist :: Integral a => [a] squareslist = [n^2 n <- [0..]] Zugriff auf die n-te Quadratzahl mit squareslist!!n, z.b. squareslist!!5 => 25 Programmieren in Haskell 3

Quadratzahlen 0 1 2 3 n 0 1 4 9 n 2 squareslist :: Integral a => [a] squareslist = [n^2 n <- [0..]] Zugriff auf die n-te Quadratzahl mit squareslist!!n, z.b. squareslist!!5 => 25 Laufzeit? Programmieren in Haskell 3

Quadratzahlen 0 1 2 3 n 0 1 4 9 n 2 squareslist :: Integral a => [a] squareslist = [n^2 n <- [0..]] Zugriff auf die n-te Quadratzahl mit squareslist!!n, z.b. squareslist!!5 => 25 Laufzeit? Θ(n) Programmieren in Haskell 3

Quadratzahlen mit Feldern (Arrays) squaresarray :: (Integral a, Ix a) => Array a a squaresarray = array (0,99) [(n,n^2) n <- [0..99]] Programmieren in Haskell 4

Quadratzahlen mit Feldern (Arrays) squaresarray :: (Integral a, Ix a) => Array a a squaresarray = array (0,99) [(n,n^2) n <- [0..99]] Zugriff auf die n-te Quadratzahl mit squaresarray!n, z.b. squaresarray!5 => 25 Programmieren in Haskell 4

Quadratzahlen mit Feldern (Arrays) squaresarray :: (Integral a, Ix a) => Array a a squaresarray = array (0,99) [(n,n^2) n <- [0..99]] Zugriff auf die n-te Quadratzahl mit squaresarray!n, z.b. squaresarray!5 => 25 Laufzeit? Programmieren in Haskell 4

Quadratzahlen mit Feldern (Arrays) squaresarray :: (Integral a, Ix a) => Array a a squaresarray = array (0,99) [(n,n^2) n <- [0..99]] Zugriff auf die n-te Quadratzahl mit squaresarray!n, z.b. squaresarray!5 => 25 Laufzeit? Θ(1) Programmieren in Haskell 4

Die Klasse Ix in der Typhierarchie Enum Eq Show / \ / Ord Num / \ / \ Ix Real Fractional / Integral Programmieren in Haskell 5

Interface der Klasse Ix class Ord a => Ix a where range :: (a,a) -> [a] index :: (a,a) -> a -> Int inrange :: (a,a) -> a -> Bool rangesize :: (a,a) -> Int Minimal complete instance : range, index, inrange Programmieren in Haskell 6

Annahmen über Ix-Instanzen inrange (l,u) i == elem i (range (l,u)) range (l,u)!! index (l,u) i == i, when inrange (l,u) i map (index (l,u)) (range (l,u))) == [0..rangeSize (l,u)-1] rangesize (l,u) == length (range (l,u)) Programmieren in Haskell 7

Beispiel data Abc = A B C deriving (Show,Eq,Ord) Programmieren in Haskell 8

Beispiel data Abc = A B C deriving (Show,Eq,Ord) instance Ix Abc where range (A,A) = [A] range (A,B) = [A,B] range (A,C) = [A,B,C] range (B,B) = [B] range (B,C) = [B,C] range (C,C) = [C] range _ = [] index (l,u) a = find 0 a (range (l,u)) where find i a (x:xs) a == x = i a > x = find (i+1) a xs find i a _ = error "Ix.index: Index out of range." inrange (l,u) a = l <= a && a <= u Programmieren in Haskell 8

range (A,C) => [A,B,C] index (A,C) B => 1 index (B,C) A => Program error: Ix.index: Index out of range. inrange (B,C) A => False Programmieren in Haskell 9

range (A,C) => [A,B,C] index (A,C) B => 1 index (B,C) A => Program error: Ix.index: Index out of range. inrange (B,C) A => False Ix-Instanzen sind auch ableitbar (für Aufzählungstypen und für Ein-Konstruktor-Typen deren Argument-Typen Instanzen von Ix sind): data Abc = A B C deriving (Show,Eq,Ord,Ix) Programmieren in Haskell 9

Funktionen auf Indextypen range :: Ix a => (a,a) -> [a] index :: Ix a => (a,a) -> a -> Int inrange :: Ix a => (a,a) -> a -> Bool rangesize :: Ix a => (a,a) -> Int array :: Ix a => (a,a) -> [(a,b)] -> Array a b bounds :: Ix a => Array a b -> (a,a) assocs :: Ix a => Array a b -> [(a,b)] (!) :: Ix a => Array a b -> a -> b Programmieren in Haskell 10

array/bounds/assocs/(!) afewsquares = array (0,4) [(n,n^2) n <- [0..4]] bounds afewsquares => (0,4) assocs afewsquares => [(0,0),(1,1),(2,4),(3,9),(4,16)] afewsquares!4 => 16 Programmieren in Haskell 11

Funktionstabellierung tabulate :: Ix a => (a -> b) -> (a,a) -> Array a b tabulate f bs = array bs [(i, f i) i <- range bs] Programmieren in Haskell 12

Anwendung: Tabellierung badfib :: Integral a => a -> a badfib 0 = 1 badfib 1 = 1 badfib n = badfib (n-2) + badfib (n-1) fib :: (Integral a, Ix a) => a -> a fib n = t!n where t = tabulate f (0,n) f 0 = 1 f 1 = 1 f n = t!(n-2) + t!(n-1) Programmieren in Haskell 13

Listen zu Felder listarray :: Ix a => (a,a) -> [b] -> Array a b -- vordefiniert listarray bs vs = array bs (zip (range bs) vs) zip :: [a] -> [b] -> [(a,b)] -- vordefiniert zip [] [] = [] zip [] (y:ys) = [] zip (x:xs) [] = [] zip (x:xs) (y:ys) = (x,y):zip xs ys zip [1..5] [ a.. z ] => [(1, a ),(2, b ),(3, c ),(4, d ),(5, e )] Programmieren in Haskell 14

Typ Ordering data Ordering = LT EQ GT -- vordefiniert compare :: Ord a => a -> a -> Ordering -- vordefiniert compare a b a < b = LT a == b = EQ a > b = GT Programmieren in Haskell 15

Anwendung: Binäre Suche binarysearch :: (Ord b, Integral a, Ix a) => Array a b -> b -> Bool binarysearch a e = within (bounds a) where within (l,r) = l <= r && let m = (l + r) div 2 in case compare e (a!m) of LT -> within (l, m-1) EQ -> True GT -> within (m+1, r) Programmieren in Haskell 16

Anwendung: Pascalsches Dreieck 0 1 2 3 4 5 6 7 8 0 1 1 1 1 2 1 2 1 3 1 3 3 1 4 1 4 6 4 1 5 1 5 10 10 5 1 6 1 6 15 20 15 6 1 7 1 7 21 35 35 21 7 1 8 1 8 28 56 70 56 28 8 1 Programmieren in Haskell 17

pascalstriangle :: Int -> Array (Int,Int) Int pascalstriangle n = a where a = array ((0,0),(n,n)) ( [((i,j),0) i <- [0..n], j <- [i+1..n]] ++ [((i,0),1) i <- [0..n]] ++ [((i,i),1) i <- [1..n]] ++ [((i,j),a!(i-1,j) + a!(i-1,j-1)) i <- [2..n], j <- [1..i-1]]) Programmieren in Haskell 18

Randbemerkung: Binomialkoeffizienten (x + y) n = nx k=0! n x k y n k k! n k = 8 < : n! (n k)!k! 0 k n 0 0 n < k, Programmieren in Haskell 19

Akkumulierende Felder accumarray :: Ix a => (b -> c -> b) -> b -> (a,a) -> [(a,c)] -> Array a b -- vordefiniert Der Ausdruck accumarray (*) e bs vs ergibt das Feld a, wobei das Feldelement a!i gleich ( ((e*c 1 )*c 2 ) )*c k ist, wenn vs dem Index i nacheinander die Werte c 1,..., c k zuordnet. Beachte: Ist die Operation (*) nicht kommutativ, spielt die Reihenfolge der Elemente in vs eine Rolle. Programmieren in Haskell 20

Anwendung: Ein lineares Sortierverfahren countingsort :: Ix a => (a,a) -> [a] -> [a] countingsort bs x = [ a (a,n) <- assocs t, i <- [1..n]] where t = accumarray (+) 0 bs [(a,1) a <- x, inrange bs a] Programmieren in Haskell 21

Anwendung: Ein lineares Sortierverfahren countingsort :: Ix a => (a,a) -> [a] -> [a] countingsort bs x = [ a (a,n) <- assocs t, i <- [1..n]] where t = accumarray (+) 0 bs [(a,1) a <- x, inrange bs a] Effizienz? Programmieren in Haskell 21

Anwendung: Ein lineares Sortierverfahren countingsort :: Ix a => (a,a) -> [a] -> [a] countingsort bs x = [ a (a,n) <- assocs t, i <- [1..n]] where t = accumarray (+) 0 bs [(a,1) a <- x, inrange bs a] Effizienz? Wenn das Intervall bs die Größe m und x die Länge n hat, sortiert countingsort in Θ(m + n). Programmieren in Haskell 21

Und Listen von Listen? listsort :: (Ix a) => (a, a) -> [[a]] -> [[a]] listsort bs xs drop 8 xs == [] = isort xs otherwise = [[] [] <- xs] ++ [a:x (a, ys) <- assocs t, x <- listsort bs ys] where t = accumarray (\y b -> b:y) [] bs [(a,x) (a:x) <- xs] Programmieren in Haskell 22

Und Listen von Listen? listsort :: (Ix a) => (a, a) -> [[a]] -> [[a]] listsort bs xs drop 8 xs == [] = isort xs otherwise = [[] [] <- xs] ++ [a:x (a, ys) <- assocs t, x <- listsort bs ys] where t = accumarray (\y b -> b:y) [] bs [(a,x) (a:x) <- xs] listsort ( A, z ) ["bla","blub","hallo","welt","marc","robert","hund", "Katze","Maus","eins","zwei","drei","wunderbar"] => ["Hund","Katze","Marc","Maus","Robert","bla","blub","drei","eins","hallo", "welt","wunderbar","zwei"] Programmieren in Haskell 22

Array-Update (//) :: (Ix a) => Array a b -> [(a, b)] -> Array a b unitmatrix :: (Ix a, Num b) => (a,a) -> Array (a,a) b unitmatrix bs@(l,r) = array bs [(ij,0) ij <- range bs ] // [((i,i),1) i <- range bs] where bs = ((l,l),(r,r)) Programmieren in Haskell 23

Anwendung: Hashing Warum Hashes? (-> schneller Zugriff UND platzsparend) Abstrakter Datentyp Hash (Schnittstelle) Hash-Implementierung als Haskell-Modul Programmieren in Haskell 24

Direkte Adressierung (kein Hashing) U (Universum der Schl"ussel) 0 1 9 4 0 7 6 2 3 1 K (Aktuelle Schl"ussel) 5 2 3 4 5 6 7 8 8 9 T Programmieren in Haskell 25

Hashing 0 U (Universum der Schl"ussel) h(k1) h(k4) K (Aktuelle Schl"ussel) k2 k4 k3 k1 k5 h(k2) = h(k5) h(k3) T m 1 Programmieren in Haskell 26

Direkte Verkettung k4 k4 k5 k2 k2 k5 Programmieren in Haskell 27

Hash-Schnittstelle emptyhash :: Int -> Hash a capacity :: Hash a -> Int loadfactor :: Fractional b => Hash a -> b insert :: (Eq a, Hashable a) => a -> Hash a -> Hash a contains :: (Eq a, Hashable a) => a -> Hash a -> Bool lookup :: (Eq a, Hashable a) => a -> Hash a -> a hashlist :: Hash a -> [a] delete :: (Eq a, Hashable a) => a -> Hash a -> Hash a update :: (Eq a, Hashable a) => a -> Hash a -> Hash a Programmieren in Haskell 28

Klasse Hashable Instanzen von Hashable haben eine Hash-Funktion definiert: class Hashable a where hashmap :: Int -> a -> Int -- hash function -- first argument is hash capacity Programmieren in Haskell 29

Annahmen über Hashes (fällt uns da noch mehr ein?) hashlist (emptyhash m) == [] for any hash capacity m contains x (insert x h) == True, if contains x h == False lookup x h == x, if contains x h == True (bag. hashlist) (delete x (insert x h)) == (bag. hashlist) h, if contains x h == False (Die Funktion bag wandelt eine Liste in eine Multimenge um.) Programmieren in Haskell 30

Ein einfacher Int-Hash instance Hashable Int where hashmap m x = x mod m inthash :: Hash Int inthash = insert 1 $ insert 2 $ insert 120 $ emptyhash 10 allints :: [Int] allints = hashlist inthash Programmieren in Haskell 31

Ein Kunden-Hash type Phone = Int type Name = String type Address = String data Customer = Customer Phone Name Address deriving Show Zwei Kunden sind gleich gdw. ihre Telefonnummern gleich sind (das ist keine Feststellung, sondern eine Definition): instance Eq Customer where (==) (Customer p ) (Customer q ) = p == q Programmieren in Haskell 32

Kunden-Hashfunktion Wir "hashen"über die Telefonnummer: instance Hashable Customer where hashmap m (Customer p ) = p mod m Programmieren in Haskell 33

customerhash :: Hash Customer customerhash = insert (Customer 13 "Robert" "Uni") $ insert (Customer 3 "Marc" "Uni") $ emptyhash 10 phone3customer :: Customer phone3customer = Hash.lookup (Customer 3 "" "") customerhash updatedcustomerhash :: Hash Customer updatedcustomerhash = update (Customer 3 "Marc" "zu Hause") customerhash updatedphone3customer :: Customer updatedphone3customer = Hash.lookup (Customer 3 "" "") updatedcustomerhash Programmieren in Haskell 34

Das Hash-Modul Programmieren in Haskell 35

module Hash( Hash, Hashable, emptyhash, capacity, loadfactor, Hash.insert, contains, Hash.lookup, hashlist, Hash.delete, update ) where -- We export only type constructor Hash, not data constructor Ha -- Thus the client cannot select the hash representation. Note: -- would export both by writing Hash(Hash). -- qualified because of ambiguity with Data.List.insert -- qualified because of ambiguity with Hugs.Prelude.lookup -- qualified because of ambiguity with Data.List.delete Programmieren in Haskell 36

Zwei Module müssen wir importieren: import Array import List Programmieren in Haskell 37

Datentyp Hash newtype Hash a = Hash (Array Int [a]) -- representation of hash as array instance Show (Hash a) where show h = "Hash" -- we don t want to show anything here Programmieren in Haskell 38

emptyhash m = Hash (array (0,m-1) [(i,[]) i <- [0..m-1]]) capacity (Hash a) = m + 1 where (0,m) = bounds a Programmieren in Haskell 39

insert x h@(hash a) contains x h = error "Hash.insert: element already in hash." otherwise = Hash (a // [(i,x:a!i)]) where m = capacity h i = hashmap m x lookup x h@(hash a) contains x h = head $ filter (==x) (a!(hashmap m x)) otherwise = error "Hash.lookup: hash does not contain element." where m = capacity h Programmieren in Haskell 40

hashlist (Hash a) = concat $ map snd (assocs a) update x h@(hash a) contains x h = Hash (a // [(i,x:(a!i \\ [x]))]) otherwise = error "Hash.update: hash does not contain element." where m = capacity h i = hashmap m x Programmieren in Haskell 41

Für die übrigen Funktionen (und sowieso): siehe Modul Hash.lhs. Anwendung: hash_test.lhs. Programmieren in Haskell 42