Programmieren in Haskell

Werbung
Programmieren
in Haskell
Stefan
Janssen
Programmieren in Haskell
Arrays
Tabellierung
Felder
Stefan Janssen
Universität Bielefeld
AG Praktische Informatik
November 5, 2014
Felder: Datenstrukturen mit konstantem Zugriff
Programmieren
in Haskell
“Felder” nennt man auch Arrays, Vektoren, Matrizen, ...
“Konstanter Zugriff” heisst:
Zugriff auf Elemente mit Aufwand unabhängig von der Größe
der Datenstruktur.
Gegenbeispiel Musik:
Finden der n-ten Note erfordert Durchlauf der
Datenstruktur in n oder mehr Schritten.
Allerdings: Die Noten sind nicht nummeriert.
Stefan
Janssen
Arrays
Tabellierung
Felder: Datenstrukturen mit konstantem Zugriff
Programmieren
in Haskell
“Felder” nennt man auch Arrays, Vektoren, Matrizen, ...
“Konstanter Zugriff” heisst:
Zugriff auf Elemente mit Aufwand unabhängig von der Größe
der Datenstruktur.
Gegenbeispiel Musik:
Finden der n-ten Note erfordert Durchlauf der
Datenstruktur in n oder mehr Schritten.
Allerdings: Die Noten sind nicht nummeriert.
Besseres Gegenbeispiel: Listen
– hier sind die Elemente ab 0 nummeriert ...
Stefan
Janssen
Arrays
Tabellierung
Zugriff auf Listenelemente
Programmieren
in Haskell
Stefan
Janssen
Listen beherbergen viele Elemente gleichen Typs.
1
2
1
2
Sequentielle Abarbeitung ist einfach und effizient, z.B.
map f [] = []
map f ( x : xs ) = f x : map f xs
Random Zugriff auf einzelne Elemente durch operator !!
hängt von der Listenlänge ab:
( x : xs ) !! 0 = x
( x : xs ) !! n = xs !!( n -1)
Abhilfe schafft der Datentyp Array a b
Arrays
Tabellierung
Datentyp Array a b
Programmieren
in Haskell
Arrays – auf Deutsch “Felder”
Modul Data.Array stellt Datentyp Array a b und
Funktionen darauf bereit
a ist der Datentyp des Index, b der Elementtyp
Operator ! für Element-Zugriff bietet effizienten
Random-Access
Indextyp erlaubt mehrere Dimensionen
Funktion array liefert ein Array zurück
Stefan
Janssen
Arrays
Tabellierung
Datentyp Array a b
Programmieren
in Haskell
Arrays – auf Deutsch “Felder”
Modul Data.Array stellt Datentyp Array a b und
Funktionen darauf bereit
a ist der Datentyp des Index, b der Elementtyp
Operator ! für Element-Zugriff bietet effizienten
Random-Access
Indextyp erlaubt mehrere Dimensionen
Funktion array liefert ein Array zurück
1
array
: : ( I x a ) => ( a , a ) −> [ ( a , b ) ] −> Array a b
2
3
t = a r r a y ( low , h i g h ) l i s t _ o f _ e n t r i e s = . . .
Stefan
Janssen
Arrays
Tabellierung
Datentyp Array a b
Programmieren
in Haskell
Arrays – auf Deutsch “Felder”
Modul Data.Array stellt Datentyp Array a b und
Funktionen darauf bereit
a ist der Datentyp des Index, b der Elementtyp
Operator ! für Element-Zugriff bietet effizienten
Random-Access
Indextyp erlaubt mehrere Dimensionen
Funktion array liefert ein Array zurück
1
array
: : ( I x a ) => ( a , a ) −> [ ( a , b ) ] −> Array a b
2
3
t = a r r a y ( low , h i g h ) l i s t _ o f _ e n t r i e s = . . .
1
(!)
:: ( Ix a ) = > Array a b -> a -> b
Stefan
Janssen
Arrays
Tabellierung
Beispiel: 2D Array
1
2
3
> module A r r
> where
> import Data . Array
Programmieren
in Haskell
> t a b l e : : Array ( Char , I n t ) I n t
> t a b l e = array ( ( ’ a ’ , 0) , ( ’ c ’ , 2) )
>
[ ( ( ’ a ’ , 0) , 0 ) ,
>
( ( ’ a ’ , 1) , 1 ) ,
>
( ( ’ a ’ , 2) , 2 ) ,
>
( ( ’b ’ , 0) , 3 ) ,
>
( ( ’b ’ , 1) , 4 ) ,
>
( ( ’ c ’ , 0) , 6 ) ,
>
( ( ’ c ’ , 1) , 7 ) ,
>
( ( ’b ’ , 2) , 5 ) ,
>
( ( ’ c ’ , 2) , 8 )
>
]
Arrays
Stefan
Janssen
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> access a b = table ! (a , b)
> access2
= ( table !)
Tabellierung
Alternative
Programmieren
in Haskell
Stefan
Janssen
Pattern Matching als Alternative für read-only Felder
vs. Feldgröße
Arrays
Tabellierung
Alternative
Programmieren
in Haskell
Stefan
Janssen
Pattern Matching als Alternative für read-only Felder
vs. Feldgröße
Tabellierung
Example
1
2
3
4
5
access
access
access
access
...
’a ’
’a ’
’a ’
’b ’
0
1
2
1
Arrays
=
=
=
=
0
1
2
3
Beispiel: Umwandlung String in Char Array
Programmieren
in Haskell
Stefan
Janssen
Arrays
Tabellierung
1
2
3
> s 2 a : : S t r i n g −> Array I n t Char
> s2a xs = l i s t A r r a y (0 , length xs − 1) xs
Akkumulierende Arrays
Programmieren
1
2
in Haskell
Manchmal kann man die Einträge eines Feldes nicht auf einmal
Stefan
ausrechnen. Dafür gibt es die Funktion
Janssen
> accumArray :: Ix a = >
Arrays
( b -> c -> b ) -> b -> (a , a ) -> [( a , c )] -> Array a b
Tabellierung
3
4
5
akkumulierende
Bereich
Fkt .
Startwert
Ergebnis
Elemente
Akkumulierende Arrays
Programmieren
1
2
in Haskell
Manchmal kann man die Einträge eines Feldes nicht auf einmal
Stefan
ausrechnen. Dafür gibt es die Funktion
Janssen
> accumArray :: Ix a = >
Arrays
( b -> c -> b ) -> b -> (a , a ) -> [( a , c )] -> Array a b
Tabellierung
3
4
5
akkumulierende
Bereich
Fkt .
Startwert
Elemente
Der Aufruf accumArray f s (lo,up) assocslist
erlaubt fehlende wie mehrfache Auftreten des Indices in
den Associations
initialisiert alle Elemente mit dem Startwert s
akkumuliert mehrfache Auftreten
(i,x),...,(i,y),...,(i,z) in der Form
(((s ‘f‘ x) ‘f‘ y) ‘f‘ z) in Element i
Ergebnis
Akkumulierende Arrays
Programmieren
in Haskell
Stefan
1
2
3
Janssen
Beispiel: Zählen der Buchstabenhäufigkeit in einem Text
> frq :: String -> Array Char Int
Arrays
> frq t = accumArray (+) 0 ( ’A ’ , ’z ’) ( zip t ones
)
Tabellierung
>
where ones = 1: ones
Akkumulierende Arrays
Programmieren
in Haskell
Stefan
1
2
3
1
2
3
4
Janssen
Beispiel: Zählen der Buchstabenhäufigkeit in einem Text
> frq :: String -> Array Char Int
Arrays
> frq t = accumArray (+) 0 ( ’A ’ , ’z ’) ( zip t ones
)
Tabellierung
>
where ones = 1: ones
Damit z.B.
Arr > frq " abraham " ! ’a ’
3
Arr > frq " abraham " ! ’U ’
0
Tabellierung von Funktionen
Gegeben eine Funktion, die aufwendig zu berechnen ist:
1
2
3
> sid
: : I n t −> I n t
> s i d x = ( x +1)∗( x −1)−(x −2)∗( x+2)+(x−round 3 . 1 )
Programmieren
in Haskell
Stefan
Janssen
Arrays
Tabellierung
Tabellierung von Funktionen
Gegeben eine Funktion, die aufwendig zu berechnen ist:
1
2
3
> sid
: : I n t −> I n t
> s i d x = ( x +1)∗( x −1)−(x −2)∗( x+2)+(x−round 3 . 1 )
Programmieren
in Haskell
Stefan
Janssen
Arrays
Tabellierung
Wenn die Werte (aus einem bekannten Intervall) immer wieder
gebraucht werden, nimmt man eine interne Tabelle
1
2
3
4
5
6
> fid
: : I n t −> I n t
> f i d = ( f ! ) where
>
f = array (0 ,100)
>
[ ( x , ( x +1)∗( x −1)−(x −2)∗( x+2)+(x−round 3 . 1 ) )
>
| x <− [ 0 . . 1 0 0 ] ]
Das funktioniert schneller, aber nur über dem vorgesehenen
Intervall.
Tabellierung von Funktionen
Programmieren
in Haskell
Tabellierung ist eine allgemeine Technik. Können wir eine
Funktion tabulate schreiben, die andere Funktionen in
tabellierte Funktionen verwandelt?
Was wäre ihr Typ?
Stefan
Janssen
Arrays
Tabellierung
Tabellierung von Funktionen
Programmieren
in Haskell
Tabellierung ist eine allgemeine Technik. Können wir eine
Funktion tabulate schreiben, die andere Funktionen in
tabellierte Funktionen verwandelt?
Was wäre ihr Typ?
1
2
> t a b u l a t e : : ( I n t , I n t )−>( I n t −>a)−>( I n t −>a )
Stefan
Janssen
Arrays
Tabellierung
Tabellierung von Funktionen
Programmieren
in Haskell
Tabellierung ist eine allgemeine Technik. Können wir eine
Funktion tabulate schreiben, die andere Funktionen in
tabellierte Funktionen verwandelt?
Was wäre ihr Typ?
1
2
> t a b u l a t e : : ( I n t , I n t )−>( I n t −>a)−>( I n t −>a )
Und was muss sie tun?
Wir fordern ∀ x, f: (tabulate f) x = f x
– nur schneller!
Stefan
Janssen
Arrays
Tabellierung
Tabellierung von Funktionen
Programmieren
in Haskell
Tabellierung ist eine allgemeine Technik. Können wir eine
Funktion tabulate schreiben, die andere Funktionen in
tabellierte Funktionen verwandelt?
Was wäre ihr Typ?
1
2
> t a b u l a t e : : ( I n t , I n t )−>( I n t −>a)−>( I n t −>a )
Und was muss sie tun?
Wir fordern ∀ x, f: (tabulate f) x = f x
– nur schneller!
1
2
3
> t a b u l a t e ( l o , up ) f = ( t ! ) where
>
t = a r r a y ( l o , up ) ( z i p domain (map f domain ) )
>
domain = [ l o . . up ]
Stefan
Janssen
Arrays
Tabellierung
Tabellierung von Funktionen
Programmieren
in Haskell
Stefan
Janssen
Damit nun einfach – für beliebige Funktionen über einem
Intervall, aber hier am Beispiel sid
1
2
3
> t i d : : I n t −> I n t
> t i d = tabulate (1 ,100) s i d
Betrachte die Anzahl der Rechenschritte bei mehrfachen
Aufrufen von sid 42, fid 42, tid 42 ...
Arrays
Tabellierung
Zugehörige Unterlagen
Herunterladen