Programmieren in Haskell

Ähnliche Dokumente
Programmieren in Haskell

Programmieren in Haskell Felder (Arrays)

Programmieren in Haskell Felder

Programmieren in Haskell

Programmieren in Haskell Programmiermethodik

Programmieren in Haskell

Programmierkurs II. Typsynonyme & algebraische Datentypen

Programmieren in Haskell Einstieg in Haskell

Typklassen. Natascha Widder

Einführung in die funktionale Programmierung

Funktionale Programmierung Grundlegende Datentypen

Programmieren in Haskell. Abstrakte Datentypen

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

Kapitel 3: Eine einfache Programmiersprache. Programmieren in Haskell 1

Funktionale Programmierung mit Haskell

Programmieren in Haskell

Programmieren in Haskell

Funktionale Programmierung mit Haskell

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

Programmieren in Haskell Das Haskell Typsystem

Programmieren in Haskell

Einführung in Haskell

Einführung in die Funktionale Programmierung mit Haskell

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

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

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

Funktionen höherer Ordnung

ALP I. Funktionale Programmierung

Abstrakte Datentypen I

Programmieren in Haskell

Übergang von funktionaler zu OOP. Algorithmen und Datenstrukturen II 1

2.3 Spezifikation von Abstrakten Datentypen

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

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

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

Programmieren in Haskell

13. Hashing. AVL-Bäume: Frage: Suche, Minimum, Maximum, Nachfolger in O(log n) Einfügen, Löschen in O(log n)

12. Hashing. Hashing einfache Methode um Wörtebücher zu implementieren, d.h. Hashing unterstützt die Operationen Search, Insert, Delete.

expr :: Expr expr = Mul (Add (Const 3) (Const 4)) (Div (Sub (Const 73) (Const 37)) (Const 6))

2.5 Listen. Kurzschreibweise: [42; 0; 16] Listen werden mithilfe von [] und :: konstruiert.

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

Agenda. 1 Einleitung. 2 Binäre Bäume. 3 Binäre Suchbäume. 4 Rose Trees. 5 Zusammenfassung & Ausblick. Haskell Bäume. Einleitung.

Hashing. Algorithmen und Datenstrukturen II 1

Funktionale Programmierung. Das Funktionale Quiz. Das Funktionale Quiz. Das Funktionale Quiz

Verarbeitung unendlicher Datenstrukturen Jetzt können wir z.b. die unendliche Liste aller geraden Zahlen oder aller Quadratzahlen berechnen:

Typklassen und Überladung in Haskell

October 29, Universität Bielefeld AG Praktische Informatik. Programmieren in Haskell. Stefan Janssen. Typ-Synonyme. Algebraische Datentypen

Programmieren in Haskell. Stefan Janssen. Strukturelle Rekursion. Universität Bielefeld AG Praktische Informatik. 10.

Basiskonstrukte von Haskell

Gliederung. Algorithmen und Datenstrukturen I. Listen in Haskell: Listen in Haskell: Listen in Haskell. Datentyp Liste Strings Listenkomprehension

WS 2011/2012. Robert Giegerich Dezember 2013

Endgültige Gruppeneinteilung Kohorte Innere-BP Sommersemester 2016 (Stand: )

Introduction to Python. Introduction. First Steps in Python. pseudo random numbers. May 2016

HASKELL KAPITEL 2.1. Notationen: Currying und das Lambda-Kalkül

Übung Algorithmen und Datenstrukturen

INFORMATIK FÜR BIOLOGEN

Dynamische Datentypen. Destruktor, Copy-Konstruktor, Zuweisungsoperator, Dynamischer Datentyp, Vektoren

zu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme

Praktische Informatik 3: Funktionale Programmierung Vorlesung 11 vom : Monaden als Berechnungsmuster

4.1 Bäume, Datenstrukturen und Algorithmen. Zunächst führen wir Graphen ein. Die einfachste Vorstellung ist, dass ein Graph gegeben ist als

Musterlösung zur 2. Aufgabe der 4. Übung

Einordnung. Was ist eigentlich eine Funktion. Funktionsdefinitionen in Haskell. Arbeit des Interpreters = Terme ausrechnen f = \x y -> x * x + 2 * y

Programmierung 1 (Wintersemester 2015/16) Wiederholungstutorium Lösungsblatt 15 (Linearer Speicher, Listen, Bäume)

5. Januar Universität Bielefeld AG Praktische Informatik. Programmieren in Haskell. Stefan Janssen. Abstrakte Datentypen.

12. Dynamische Datenstrukturen

Modul 122 VBA Scribt.docx

Funktionale Programmierung mit Haskell. Jan Hermanns

Zahlen in Haskell Kapitel 3

Die Korrektheit von Mergesort

Stacks, Queues & Bags. Datenstrukturen. Pushdown/Popup Stack. Ferd van Odenhoven. 19. September 2012

Übergang von funktionaler zu OOP. Algorithmen und Datenstrukturen II 1

Einführung in die Informatik 2

Teil VII. Hashverfahren

VL06: Haskell (Funktionen höherer Ordnung, Currying)

Informatik-Seminar Thema: Monaden (Kapitel 10)

Ursprünge. Die Syntax von Java. Das Wichtigste in Kürze. Konsequenzen. Weiteres Vorgehen. Rund um Java

Verschlüsseln eines Bildes. Visuelle Kryptographie. Verschlüsseln eines Bildes. Verschlüsseln eines Bildes

zu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme

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 Hashing (anspruchsvolles Projekt) Programmieren in Haskell 2

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]] 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 index inrange :: (a,a) -> [a] :: (a,a) -> a -> Int :: (a,a) -> a -> Bool rangesize :: (a,a) -> Int range (a,b) liefert eine Liste aller Elemente zwischen a und b: Array> range (1,5) [1,2,3,4,5] index (a,b) c liefert den Index des Wertes c im Bereich (a,b) Array> index (3,5) 3 0 Programmieren in Haskell 6

inrange (a,b) c gibt aus, ob sich der Wert c innerhalb des Bereichs (a,b) befindet Array> inrange (1,5) 3 True rangesize (a,b) liefert die Grösse des Bereichs (a,b) Array> rangesize (1,5) 5 Programmieren in Haskell 7

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 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 Programmieren in Haskell 10

range :: Ix a => (a,a) -> [a] -- liefert die Liste aller Elemente zwischen a und b index :: Ix a => (a,a) -> a -> Int -- liefert den Index eines Wertes im Bereich (a,b) inrange :: Ix a => (a,a) -> a -> Bool -- bestimmt, ob sich ein Wert c im Bereich (a,b) befindet rangesize :: Ix a => (a,a) -> Int -- gibt die Groesse des Bereichs (a,b) zurueck array :: Ix a => (a,a) -> [(a,b)] -> Array a b -- erstellt ein Array der Dimension (a,b) bounds :: Ix a => Array a b -> (a,a) -- gibt die Dimensionen eines Arrays zurueck assocs :: Ix a => Array a b -> [(a,b)] -- gibt den Inhalt eines Arrays zurueck (!) :: Ix a => Array a b -> a -> b -- liefert den Wert eines Arrays an einer bestimmten Position Programmieren in Haskell 11

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 12

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 13

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 14

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 15

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 16

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 17

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 18

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 19

Anzeigen eines zweidimensionalen Arrays showarray :: (Show a, Ix b, Ix c, Enum b, Enum c) => Array (c,b) a -> IO () showarray arr = let ((lx,ly),(ux,uy)) = bounds arr row r = concat [ show (arr!(r,c)) ++ " " c <- [ly.. uy]] rows = concat [ row r ++ "\n" r <- [lx.. ux]] in putstrln rows Main> showarray (pascalstriangle 5) 1 0 0 0 0 0 1 1 0 0 0 0 1 2 1 0 0 0 1 3 3 1 0 0 1 4 6 4 1 0 1 5 10 10 5 1 Programmieren in Haskell 20

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 21

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

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 23

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 24

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

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 26

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 27

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 28

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 29

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 30

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

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 32

Das Hash-Modul Programmieren in Haskell 33

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 34

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

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 36

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 37

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 38

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 39

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