• Keine Ergebnisse gefunden

Problem: Zwischenergebnisse Ein Beispiel: filter

N/A
N/A
Protected

Academic year: 2022

Aktie "Problem: Zwischenergebnisse Ein Beispiel: filter"

Copied!
84
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Problem: Zwischenergebnisse

Ein Beispiel:

filter((== 1)◦(‘mod‘3)) (map (ˆ2) [1..5])

= filter((== 1)◦(‘mod‘3)) (1: (map (ˆ2) [2..5]))

= 1: (filter ((==1)◦(‘mod‘3)) (map (ˆ2) [2..5]))

= 1: (filter ((==1)◦(‘mod‘3)) (4: (map (ˆ2) [3..5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [3..5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (9: (map (ˆ2) [4,5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [4,5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (16: (map (ˆ2) [5])))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [5]))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (25: (map (ˆ2) [ ])))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [ ]))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) [ ] )

= 1:4:16:25: [ ]

(2)

Problem: Zwischenergebnisse

Ein Beispiel:

filter((== 1)◦(‘mod‘3)) (map (ˆ2) [1..5])

= filter((== 1)◦(‘mod‘3)) (1: (map (ˆ2) [2..5]))

= 1: (filter ((==1)◦(‘mod‘3)) (map (ˆ2) [2..5]))

= 1: (filter ((==1)◦(‘mod‘3)) (4: (map (ˆ2) [3..5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [3..5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (9: (map (ˆ2) [4,5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [4,5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (16: (map (ˆ2) [5])))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [5]))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (25: (map (ˆ2) [ ])))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [ ]))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) [ ] )

= 1:4:16:25: [ ]

1

(3)

Problem: Zwischenergebnisse

Ein Beispiel:

filter((== 1)◦(‘mod‘3)) (map (ˆ2) [1..5])

= filter((== 1)◦(‘mod‘3)) (1: (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [2..5]))

= 1: (filter ((==1)◦(‘mod‘3)) (4: (map (ˆ2) [3..5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [3..5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (9: (map (ˆ2) [4,5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [4,5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (16: (map (ˆ2) [5])))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [5]))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (25: (map (ˆ2) [ ])))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [ ]))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) [ ] )

= 1:4:16:25: [ ]

(4)

Problem: Zwischenergebnisse

Ein Beispiel:

filter((== 1)◦(‘mod‘3)) (map (ˆ2) [1..5])

= filter((== 1)◦(‘mod‘3)) (1: (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (4: (map (ˆ2) [3..5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [3..5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (9: (map (ˆ2) [4,5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [4,5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (16: (map (ˆ2) [5])))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [5]))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (25: (map (ˆ2) [ ])))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [ ]))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) [ ] )

= 1:4:16:25: [ ]

1

(5)

Problem: Zwischenergebnisse

Ein Beispiel:

filter((== 1)◦(‘mod‘3)) (map (ˆ2) [1..5])

= filter((== 1)◦(‘mod‘3)) (1: (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (4: (map (ˆ2) [3..5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [3..5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (9: (map (ˆ2) [4,5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [4,5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (16: (map (ˆ2) [5])))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [5]))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (25: (map (ˆ2) [ ])))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [ ]))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) [ ] )

= 1:4:16:25: [ ]

(6)

Problem: Zwischenergebnisse

Ein Beispiel:

filter((== 1)◦(‘mod‘3)) (map (ˆ2) [1..5])

= filter((== 1)◦(‘mod‘3)) (1: (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (4: (map (ˆ2) [3..5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [3..5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (9: (map (ˆ2) [4,5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [4,5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (16: (map (ˆ2) [5])))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [5]))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (25: (map (ˆ2) [ ])))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [ ]))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) [ ] )

= 1:4:16:25: [ ]

1

(7)

Problem: Zwischenergebnisse

Ein Beispiel:

filter((== 1)◦(‘mod‘3)) (map (ˆ2) [1..5])

= filter((== 1)◦(‘mod‘3)) (1: (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (4: (map (ˆ2) [3..5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [3..5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (9: (map (ˆ2) [4,5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [4,5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (16: (map (ˆ2) [5])))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [5]))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (25: (map (ˆ2) [ ])))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [ ]))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) [ ] )

= 1:4:16:25: [ ]

(8)

Problem: Zwischenergebnisse

Ein Beispiel:

filter((== 1)◦(‘mod‘3)) (map (ˆ2) [1..5])

= filter((== 1)◦(‘mod‘3)) (1: (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (4: (map (ˆ2) [3..5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [3..5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (9: (map (ˆ2) [4,5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [4,5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (16: (map (ˆ2) [5])))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [5]))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (25: (map (ˆ2) [ ])))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [ ]))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) [ ] )

= 1:4:16:25: [ ]

1

(9)

Problem: Zwischenergebnisse

Ein Beispiel:

filter((== 1)◦(‘mod‘3)) (map (ˆ2) [1..5])

= filter((== 1)◦(‘mod‘3)) (1: (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (4: (map (ˆ2) [3..5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [3..5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (9: (map (ˆ2) [4,5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [4,5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (16: (map (ˆ2) [5])))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [5]))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (25: (map (ˆ2) [ ])))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [ ]))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) [ ] )

= 1:4:16:25: [ ]

(10)

Problem: Zwischenergebnisse

Ein Beispiel:

filter((== 1)◦(‘mod‘3)) (map (ˆ2) [1..5])

= filter((== 1)◦(‘mod‘3)) (1: (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (4: (map (ˆ2) [3..5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [3..5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (9: (map (ˆ2) [4,5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [4,5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (16: (map (ˆ2) [5])))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [5]))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (25: (map (ˆ2) [ ])))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [ ]))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) [ ] )

= 1:4:16:25: [ ]

1

(11)

Problem: Zwischenergebnisse

Ein Beispiel:

filter((== 1)◦(‘mod‘3)) (map (ˆ2) [1..5])

= filter((== 1)◦(‘mod‘3)) (1: (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (4: (map (ˆ2) [3..5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [3..5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (9: (map (ˆ2) [4,5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [4,5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (16: (map (ˆ2) [5])))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [5]))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (25: (map (ˆ2) [ ])))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [ ]))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) [ ] )

= 1:4:16:25: [ ]

(12)

Problem: Zwischenergebnisse

Ein Beispiel:

filter((== 1)◦(‘mod‘3)) (map (ˆ2) [1..5])

= filter((== 1)◦(‘mod‘3)) (1: (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (4: (map (ˆ2) [3..5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [3..5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (9: (map (ˆ2) [4,5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [4,5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (16: (map (ˆ2) [5])))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [5]))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (25: (map (ˆ2) [ ])))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [ ]))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) [ ] )

= 1:4:16:25: [ ]

1

(13)

Problem: Zwischenergebnisse

Ein Beispiel:

filter((== 1)◦(‘mod‘3)) (map (ˆ2) [1..5])

= filter((== 1)◦(‘mod‘3)) (1: (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (4: (map (ˆ2) [3..5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [3..5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (9: (map (ˆ2) [4,5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [4,5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (16: (map (ˆ2) [5])))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [5]))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (25: (map (ˆ2) [ ])))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [ ]))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) [ ] )

(14)

Problem: Zwischenergebnisse

Ein Beispiel:

filter((== 1)◦(‘mod‘3)) (map (ˆ2) [1..5])

= filter((== 1)◦(‘mod‘3)) (1: (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (4: (map (ˆ2) [3..5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [3..5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (9: (map (ˆ2) [4,5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [4,5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (16: (map (ˆ2) [5])))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [5]))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (25: (map (ˆ2) [ ])))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [ ]))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) [ ] )

= 1:4:16:25: [ ]

1

(15)

Freies Theorem als Lösung?

Wir hatten, für jede Wahl vonp,h und l:

filterp (maph l) = map h (filter(p◦h) l)

Warum nicht einfache linke Seite durch rechte Seite ersetzen?

Probleme:

• immer noch zwei Durchläufe, bzw. Zwischenergebnis

• Gefahr von Doppelarbeit für h

• wenn Verlass nur auf Typ vonfilter:

I andere Funktion gleichen Typs könnte Listeverlängern

I . . . und/oderElemente verdoppeln

(16)

Freies Theorem als Lösung?

Wir hatten, für jede Wahl vonp,h und l:

filterp (maph l) = map h (filter(p◦h) l)

Warum nicht einfache linke Seite durch rechte Seite ersetzen?

Probleme:

• immer noch zwei Durchläufe, bzw. Zwischenergebnis

• Gefahr von Doppelarbeit für h

• wenn Verlass nur auf Typ vonfilter:

I andere Funktion gleichen Typs könnte Listeverlängern

I . . . und/oderElemente verdoppeln

2

(17)

Freies Theorem als Lösung?

Wir hatten, für jede Wahl vonp,h und l:

filterp (maph l) = map h (filter(p◦h) l)

Warum nicht einfache linke Seite durch rechte Seite ersetzen?

Probleme:

• immer noch zwei Durchläufe, bzw. Zwischenergebnis

• Gefahr von Doppelarbeit für h

• wenn Verlass nur auf Typ vonfilter:

I andere Funktion gleichen Typs könnte Listeverlängern

I . . . und/oderElemente verdoppeln

(18)

Freies Theorem als Lösung?

Wir hatten, für jede Wahl vonp,h und l:

filterp (maph l) = map h (filter(p◦h) l)

Warum nicht einfache linke Seite durch rechte Seite ersetzen?

Probleme:

• immer noch zwei Durchläufe, bzw. Zwischenergebnis

• Gefahr von Doppelarbeit für h

• wenn Verlass nur auf Typ vonfilter:

I andere Funktion gleichen Typs könnte Listeverlängern

I . . . und/oderElemente verdoppeln

2

(19)

Freies Theorem als Lösung?

Wir hatten, für jede Wahl vonp,h und l:

filterp (maph l) = map h (filter(p◦h) l)

Warum nicht einfache linke Seite durch rechte Seite ersetzen?

Probleme:

• immer noch zwei Durchläufe, bzw. Zwischenergebnis

• Gefahr von Doppelarbeit für h

• wenn Verlass nur auf Typ vonfilter:

I andere Funktion gleichen Typs könnte Listeverlängern

I . . . und/oderElemente verdoppeln

(20)

Freies Theorem als Lösung?

Wir hatten, für jede Wahl vonp,h und l:

filterp (maph l) = map h (filter(p◦h) l)

Warum nicht einfache linke Seite durch rechte Seite ersetzen?

Probleme:

• immer noch zwei Durchläufe, bzw. Zwischenergebnis

• Gefahr von Doppelarbeit für h

• wenn Verlass nur auf Typ vonfilter:

I andere Funktion gleichen Typs könnte Listeverlängern

I . . . und/oderElemente verdoppeln

2

(21)

Freies Theorem als Lösung?

Wir hatten, für jede Wahl vonp,h und l:

filterp (maph l) = map h (filter(p◦h) l)

Warum nicht einfache linke Seite durch rechte Seite ersetzen?

Probleme:

• immer noch zwei Durchläufe, bzw. Zwischenergebnis

• Gefahr von Doppelarbeit für h

• wenn Verlass nur auf Typ vonfilter:

I andere Funktion gleichen Typs könnte Listeverlängern

I . . . und/oderElemente verdoppeln

(22)

Versuch Herleitung effizienter Lösung „per Hand“

Man ersetze zunächst einfach wie folgt:

filterp (map h l) filterMap p h l

für eine angenommene neue Funktion:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h l =filterp (maph l)

Dann, Verfeinerung und Optimierung dieser Funktion. Zum Beispiel durch Instanziierung:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] =filterp (map h [ ]) filterMapp h (a:as) =filterp (map h (a:as)) Und Anwendung bekannter Definitionen:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h[ ] =filter p [ ]

filterMap p h(a:as) =filter p ((h a) : (map h as)) Gegebenenfalls wiederholt:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filter p (map h as))

| otherwise=filterp (maph as) Wenn möglich, Rückgriff auf ursprünglich postulierte Gleichung:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h l =filterp (maph l)

Also:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as

3

(23)

Versuch Herleitung effizienter Lösung „per Hand“

Man ersetze zunächst einfach wie folgt:

filterp (map h l) filterMap p h l für eine angenommene neue Funktion:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h l =filterp (maph l)

Dann, Verfeinerung und Optimierung dieser Funktion. Zum Beispiel durch Instanziierung:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] =filterp (map h [ ]) filterMapp h (a:as) =filterp (map h (a:as)) Und Anwendung bekannter Definitionen:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h[ ] =filter p [ ]

filterMap p h(a:as) =filter p ((h a) : (map h as)) Gegebenenfalls wiederholt:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filter p (map h as))

| otherwise=filterp (maph as) Wenn möglich, Rückgriff auf ursprünglich postulierte Gleichung:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h l =filterp (maph l)

Also:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as

(24)

Versuch Herleitung effizienter Lösung „per Hand“

Man ersetze zunächst einfach wie folgt:

filterp (map h l) filterMap p h l für eine angenommene neue Funktion:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h l =filterp (maph l)

Dann, Verfeinerung und Optimierung dieser Funktion.

Zum Beispiel durch Instanziierung:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] =filterp (map h [ ]) filterMapp h (a:as) =filterp (map h (a:as)) Und Anwendung bekannter Definitionen:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h[ ] =filter p [ ]

filterMap p h(a:as) =filter p ((h a) : (map h as)) Gegebenenfalls wiederholt:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filter p (map h as))

| otherwise=filterp (maph as) Wenn möglich, Rückgriff auf ursprünglich postulierte Gleichung:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h l =filterp (maph l)

Also:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as

3

(25)

Versuch Herleitung effizienter Lösung „per Hand“

Man ersetze zunächst einfach wie folgt:

filterp (map h l) filterMap p h l für eine angenommene neue Funktion:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h l =filterp (maph l)

Dann, Verfeinerung und Optimierung dieser Funktion.

Zum Beispiel durch Instanziierung:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] =filterp (map h [ ]) filterMapp h (a:as) =filterp (map h (a:as))

Und Anwendung bekannter Definitionen:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h[ ] =filter p [ ]

filterMap p h(a:as) =filter p ((h a) : (map h as)) Gegebenenfalls wiederholt:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filter p (map h as))

| otherwise=filterp (maph as) Wenn möglich, Rückgriff auf ursprünglich postulierte Gleichung:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h l =filterp (maph l)

Also:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as

(26)

Versuch Herleitung effizienter Lösung „per Hand“

Man ersetze zunächst einfach wie folgt:

filterp (map h l) filterMap p h l für eine angenommene neue Funktion:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h l =filterp (maph l)

Dann, Verfeinerung und Optimierung dieser Funktion.

Zum Beispiel durch Instanziierung:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] =filterp (map h [ ]) filterMapp h (a:as) =filterp (map h (a:as)) Und Anwendung bekannter Definitionen:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h[ ] =filter p [ ]

filterMap p h(a:as) =filter p ((h a) : (map h as))

Gegebenenfalls wiederholt:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filter p (map h as))

| otherwise=filterp (maph as) Wenn möglich, Rückgriff auf ursprünglich postulierte Gleichung:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h l =filterp (maph l)

Also:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as

3

(27)

Versuch Herleitung effizienter Lösung „per Hand“

Dann, Verfeinerung und Optimierung dieser Funktion.

Zum Beispiel durch Instanziierung:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] =filterp (map h [ ]) filterMapp h (a:as) =filterp (map h (a:as)) Und Anwendung bekannter Definitionen:

filterMap:: (b→Bool)→(a→b)→[a]→[b]

filterMap p h[ ] =filter p [ ]

filterMap p h(a:as) =filter p ((h a) : (map h as)) Gegebenenfalls wiederholt:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filter p (map h as))

| otherwise=filterp (maph as) Wenn möglich, Rückgriff auf ursprünglich postulierte Gleichung:

filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h l =filterp (maph l)

Also:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as

(28)

Versuch Herleitung effizienter Lösung „per Hand“

Dann, Verfeinerung und Optimierung dieser Funktion.

Zum Beispiel durch Instanziierung:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] =filterp (map h [ ]) filterMapp h (a:as) =filterp (map h (a:as)) Und Anwendung bekannter Definitionen:

filterMap:: (b→Bool)→(a→b)→[a]→[b]

filterMap p h[ ] =filter p [ ]

filterMap p h(a:as) =filter p ((h a) : (map h as)) Gegebenenfalls wiederholt:

filterMap:: (b →Bool)→(a→b)→[a]→[b]

filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filter p (map h as))

| otherwise=filterp (map h as)

Wenn möglich, Rückgriff auf ursprünglich postulierte Gleichung: filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h l =filterp (maph l)

Also:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as

3

(29)

Versuch Herleitung effizienter Lösung „per Hand“

Dann, Verfeinerung und Optimierung dieser Funktion.

Gegebenenfalls wiederholt:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filter p (map h as))

| otherwise=filterp (map h as)

Wenn möglich, Rückgriff auf ursprünglich postulierte Gleichung: filterMap:: (b→Bool)→(a→b)→[a]→[b] filterMap p h l =filterp (maph l)

Also:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as

(30)

Versuch Herleitung effizienter Lösung „per Hand“

Dann, Verfeinerung und Optimierung dieser Funktion.

Gegebenenfalls wiederholt:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filter p (map h as))

| otherwise=filterp (map h as) Wenn möglich, Rückgriff auf ursprünglich postulierte Gleichung:

filterMap:: (b→Bool)→(a→b)→[a]→[b]

filterMap p h l =filterp (maph l)

Also:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as

3

(31)

Versuch Herleitung effizienter Lösung „per Hand“

Dann, Verfeinerung und Optimierung dieser Funktion.

Gegebenenfalls wiederholt:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filter p (map h as))

| otherwise=filterp (map h as) Wenn möglich, Rückgriff auf ursprünglich postulierte Gleichung:

filterMap:: (b→Bool)→(a→b)→[a]→[b]

filterMap p h l =filterp (maph l) Also:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

(32)

Probleme mit diesem Ansatz

Im Beispiel erzeugte Funktion:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as ist potentiell ineffizient wegen Verdopplung des Ausdrucks „(h a)“.

Weitere Probleme im Allgemeinen:

• Termination der Transformation (und somit des Compilers)

• Beliebige Berechnungen zur Compile-Zeit

• Geeigneter Rückgriff auf vorherige Definitionen nötig

• Wenn „unvorsichtig“, sogar Termination des Programms fraglich

• Einschränkungen nötig, sonst Aufwandsverdopplung möglich

• hoher Implementierungsaufwand

4

(33)

Probleme mit diesem Ansatz

Im Beispiel erzeugte Funktion:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as ist potentiell ineffizient wegen Verdopplung des Ausdrucks „(h a)“.

Weitere Probleme im Allgemeinen:

• Termination der Transformation (und somit des Compilers)

• Beliebige Berechnungen zur Compile-Zeit

• Geeigneter Rückgriff auf vorherige Definitionen nötig

• Wenn „unvorsichtig“, sogar Termination des Programms fraglich

• Einschränkungen nötig, sonst Aufwandsverdopplung möglich

• hoher Implementierungsaufwand

(34)

Probleme mit diesem Ansatz

Im Beispiel erzeugte Funktion:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as ist potentiell ineffizient wegen Verdopplung des Ausdrucks „(h a)“.

Weitere Probleme im Allgemeinen:

• Termination der Transformation (und somit des Compilers)

• Beliebige Berechnungen zur Compile-Zeit

• Geeigneter Rückgriff auf vorherige Definitionen nötig

• Wenn „unvorsichtig“, sogar Termination des Programms fraglich

• Einschränkungen nötig, sonst Aufwandsverdopplung möglich

• hoher Implementierungsaufwand

4

(35)

Probleme mit diesem Ansatz

Im Beispiel erzeugte Funktion:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as ist potentiell ineffizient wegen Verdopplung des Ausdrucks „(h a)“.

Weitere Probleme im Allgemeinen:

• Termination der Transformation (und somit des Compilers)

• Beliebige Berechnungen zur Compile-Zeit

• Geeigneter Rückgriff auf vorherige Definitionen nötig

• Wenn „unvorsichtig“, sogar Termination des Programms fraglich

• Einschränkungen nötig, sonst Aufwandsverdopplung möglich

• hoher Implementierungsaufwand

(36)

Probleme mit diesem Ansatz

Im Beispiel erzeugte Funktion:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as ist potentiell ineffizient wegen Verdopplung des Ausdrucks „(h a)“.

Weitere Probleme im Allgemeinen:

• Termination der Transformation (und somit des Compilers)

• Beliebige Berechnungen zur Compile-Zeit

• Geeigneter Rückgriff auf vorherige Definitionen nötig

• Wenn „unvorsichtig“, sogar Termination des Programms fraglich

• Einschränkungen nötig, sonst Aufwandsverdopplung möglich

• hoher Implementierungsaufwand

4

(37)

Probleme mit diesem Ansatz

Im Beispiel erzeugte Funktion:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as ist potentiell ineffizient wegen Verdopplung des Ausdrucks „(h a)“.

Weitere Probleme im Allgemeinen:

• Termination der Transformation (und somit des Compilers)

• Beliebige Berechnungen zur Compile-Zeit

• Geeigneter Rückgriff auf vorherige Definitionen nötig

• Wenn „unvorsichtig“, sogar Termination des Programms fraglich

• Einschränkungen nötig, sonst Aufwandsverdopplung möglich

• hoher Implementierungsaufwand

(38)

Probleme mit diesem Ansatz

Im Beispiel erzeugte Funktion:

filterMap:: (b →Bool)→(a→b)→[a]→[b] filterMapp h [ ] = [ ]

filterMapp h (a:as) | p (h a) = (h a) : (filterMap p h as)

| otherwise=filterMapp h as ist potentiell ineffizient wegen Verdopplung des Ausdrucks „(h a)“.

Weitere Probleme im Allgemeinen:

• Termination der Transformation (und somit des Compilers)

• Beliebige Berechnungen zur Compile-Zeit

• Geeigneter Rückgriff auf vorherige Definitionen nötig

• Wenn „unvorsichtig“, sogar Termination des Programms fraglich

• Einschränkungen nötig, sonst Aufwandsverdopplung möglich

• hoher Implementierungsaufwand

4

(39)

Populäre Strategie: Deforestation [Wadler 1990]

Funktioniert zum Beispiel fürfilterp (maph l), nach geeigneter Anpassung für higher-order.

Aber bringt keine Verbesserung zum Beispiel fürmap h (reverse l) mit effizientemreverse:

mapReverse:: (a→b)→[a]→[b] mapReverseh l =map h (reverse l) mapReverseh l =map h (reverse0 l [ ])

mapReverseh l =mapReverse0 h l [ ]

mapReverse0 :: (a→b)→[a]→[a]→[b] mapReverse0 h l l0 =map h (reverse0 l l0)

mapReverse0 h [ ] l0 =map h (reverse0 [ ] l0) mapReverse0 h (a:as) l0 =map h (reverse0 (a:as)l0)

mapReverse0 h [ ] l0 =map h l0

mapReverse0 h (a:as) l0 =map h (reverse0 as (a:l0))

mapReverse0 h (a:as) l0 =mapReverse0 h as (a:l0)

(40)

Populäre Strategie: Deforestation [Wadler 1990]

Funktioniert zum Beispiel fürfilterp (maph l), nach geeigneter Anpassung für higher-order.

Aber bringt keine Verbesserung zum Beispiel fürmap h (reverse l) mit effizientemreverse:

mapReverse:: (a→b)→[a]→[b] mapReverseh l =map h (reverse l) mapReverseh l =map h (reverse0 l [ ])

mapReverseh l =mapReverse0 h l [ ]

mapReverse0 :: (a→b)→[a]→[a]→[b] mapReverse0 h l l0 =map h (reverse0 l l0)

mapReverse0 h [ ] l0 =map h (reverse0 [ ] l0) mapReverse0 h (a:as) l0 =map h (reverse0 (a:as)l0)

mapReverse0 h [ ] l0 =map h l0

mapReverse0 h (a:as) l0 =map h (reverse0 as (a:l0))

mapReverse0 h (a:as) l0 =mapReverse0 h as (a:l0)

5

(41)

Populäre Strategie: Deforestation [Wadler 1990]

Funktioniert zum Beispiel fürfilterp (maph l), nach geeigneter Anpassung für higher-order.

Aber bringt keine Verbesserung zum Beispiel fürmap h (reverse l) mit effizientemreverse:

mapReverse:: (a→b)→[a]→[b] mapReverseh l =map h (reverse l)

mapReverseh l =map h (reverse0 l [ ])

mapReverseh l =mapReverse0 h l [ ]

mapReverse0 :: (a→b)→[a]→[a]→[b] mapReverse0 h l l0 =map h (reverse0 l l0)

mapReverse0 h [ ] l0 =map h (reverse0 [ ] l0) mapReverse0 h (a:as) l0 =map h (reverse0 (a:as)l0)

mapReverse0 h [ ] l0 =map h l0

mapReverse0 h (a:as) l0 =map h (reverse0 as (a:l0))

mapReverse0 h (a:as) l0 =mapReverse0 h as (a:l0)

(42)

Populäre Strategie: Deforestation [Wadler 1990]

Funktioniert zum Beispiel fürfilterp (maph l), nach geeigneter Anpassung für higher-order.

Aber bringt keine Verbesserung zum Beispiel fürmap h (reverse l) mit effizientemreverse:

mapReverse:: (a→b)→[a]→[b] mapReverseh l =map h (reverse l) mapReverseh l =map h (reverse0 l [ ])

mapReverseh l =mapReverse0 h l [ ]

mapReverse0 :: (a→b)→[a]→[a]→[b] mapReverse0 h l l0 =map h (reverse0 l l0)

mapReverse0 h [ ] l0 =map h (reverse0 [ ] l0) mapReverse0 h (a:as) l0 =map h (reverse0 (a:as)l0)

mapReverse0 h [ ] l0 =map h l0

mapReverse0 h (a:as) l0 =map h (reverse0 as (a:l0))

mapReverse0 h (a:as) l0 =mapReverse0 h as (a:l0)

5

(43)

Populäre Strategie: Deforestation [Wadler 1990]

Funktioniert zum Beispiel fürfilterp (maph l), nach geeigneter Anpassung für higher-order.

Aber bringt keine Verbesserung zum Beispiel fürmap h (reverse l) mit effizientemreverse:

mapReverse:: (a→b)→[a]→[b] mapReverseh l =map h (reverse l) mapReverseh l =map h (reverse0 l [ ])

mapReverseh l =mapReverse0 h l [ ]

mapReverse0 :: (a→b)→[a]→[a]→[b] mapReverse0 h l l0 =map h (reverse0 l l0)

mapReverse0 h [ ] l0 =map h (reverse0 [ ] l0) mapReverse0 h (a:as) l0 =map h (reverse0 (a:as)l0)

mapReverse0 h [ ] l0 =map h l0

mapReverse0 h (a:as) l0 =map h (reverse0 as (a:l0))

mapReverse0 h (a:as) l0 =mapReverse0 h as (a:l0)

(44)

Populäre Strategie: Deforestation [Wadler 1990]

Funktioniert zum Beispiel fürfilterp (maph l), nach geeigneter Anpassung für higher-order.

Aber bringt keine Verbesserung zum Beispiel fürmap h (reverse l) mit effizientemreverse:

mapReverse:: (a→b)→[a]→[b] mapReverseh l =map h (reverse l) mapReverseh l =map h (reverse0 l [ ])

mapReverseh l =mapReverse0 h l [ ]

mapReverse0 :: (a→b)→[a]→[a]→[b] mapReverse0 h l l0 =map h (reverse0 l l0)

mapReverse0 h [ ] l0 =map h (reverse0 [ ] l0) mapReverse0 h (a:as) l0 =map h (reverse0 (a:as) l0)

mapReverse0 h [ ] l0 =map h l0

mapReverse0 h (a:as) l0 =map h (reverse0 as (a:l0))

mapReverse0 h (a:as) l0 =mapReverse0 h as (a:l0)

5

(45)

Populäre Strategie: Deforestation [Wadler 1990]

Funktioniert zum Beispiel fürfilterp (maph l), nach geeigneter Anpassung für higher-order.

Aber bringt keine Verbesserung zum Beispiel fürmap h (reverse l) mit effizientemreverse:

mapReverse:: (a→b)→[a]→[b] mapReverseh l =map h (reverse l) mapReverseh l =map h (reverse0 l [ ])

mapReverseh l =mapReverse0 h l [ ]

mapReverse0 :: (a→b)→[a]→[a]→[b] mapReverse0 h l l0 =map h (reverse0 l l0)

mapReverse0 h [ ] l0 =map h (reverse0 [ ] l0) mapReverse0 h (a:as) l0 =map h (reverse0 (a:as) l0)

mapReverse0 h [ ] l0 =map h l0

mapReverse0 h (a:as) l0 =map h (reverse0 as (a:l0))

mapReverse0 h (a:as) l0 =mapReverse0 h as (a:l0)

(46)

Populäre Strategie: Deforestation [Wadler 1990]

Funktioniert zum Beispiel fürfilterp (maph l), nach geeigneter Anpassung für higher-order.

Aber bringt keine Verbesserung zum Beispiel fürmap h (reverse l) mit effizientemreverse:

mapReverse:: (a→b)→[a]→[b] mapReverseh l =map h (reverse l) mapReverseh l =map h (reverse0 l [ ])

mapReverseh l =mapReverse0 h l [ ]

mapReverse0 :: (a→b)→[a]→[a]→[b] mapReverse0 h l l0 =map h (reverse0 l l0)

mapReverse0 h [ ] l0 =map h (reverse0 [ ] l0) mapReverse0 h (a:as) l0 =map h (reverse0 (a:as) l0)

mapReverse0 h [ ] l0 =map h l0

mapReverse0 h (a:as) l0 =map h (reverse0 as (a:l0))

mapReverse0 h (a:as) l0 =mapReverse0 h as (a:l0)

5

(47)

Populäre Strategie: Deforestation [Wadler 1990]

Funktioniert zum Beispiel fürfilterp (maph l), nach geeigneter Anpassung für higher-order.

Aber bringt keine Verbesserung zum Beispiel fürmap h (reverse l) mit effizientemreverse:

mapReverse:: (a→b)→[a]→[b] mapReverseh l =map h (reverse l) mapReverseh l =map h (reverse0 l [ ])

→ mapReverseh l =mapReverse0 h l [ ] mapReverse0 :: (a→b)→[a]→[a]→[b] mapReverse0 h l l0 =map h (reverse0 l l0)

mapReverse0 h [ ] l0 =map h (reverse0 [ ] l0) mapReverse0 h (a:as) l0 =map h (reverse0 (a:as) l0)

→ mapReverse0 h [ ] l0 =map h l0

mapReverse0 h (a:as) l0 =map h (reverse0 as (a:l0))

(48)

Weniger Syntax — Mehr Struktur

Man könnte es ja auch mal mitfoldr-fusion versuchen:

h (foldr f k l) = foldr g (h k)l sofern für allex und y,

h (f x y) = g x (h y)

Also, umformulieren:

map h l =foldr (λx ys →(h x) :ys) [ ] l

Folglich:

filterp (map h l) = foldrg (filterp [ ])l sofern für allex und ys,

filterp ((h x) :ys) = g x (filter p ys)

6

(49)

Weniger Syntax — Mehr Struktur

Man könnte es ja auch mal mitfoldr-fusion versuchen:

h (foldr f k l) = foldr g (h k)l sofern für allex und y,

h (f x y) = g x (h y)

Also, umformulieren:

map h l =foldr (λx ys →(h x) :ys) [ ] l

Folglich:

filterp (map h l) = foldrg (filterp [ ])l sofern für allex und ys,

filterp ((h x) :ys) = g x (filter p ys)

(50)

Weniger Syntax — Mehr Struktur

Man könnte es ja auch mal mitfoldr-fusion versuchen:

h (foldr f k l) = foldr g (h k)l sofern für allex und y,

h (f x y) = g x (h y)

Also, umformulieren:

map h l =foldr (λx ys →(h x) :ys) [ ] l

Folglich:

filterp (map h l) = foldrg (filterp [ ])l sofern für allex und ys,

filterp ((h x) :ys) = g x (filter p ys)

6

(51)

Weniger Syntax — Mehr Struktur

Die Bedingung

filterp ((h x) :ys) = g x (filter p ys) lässt sich weiter analysieren:

filterp ((h x) :ys)

=

let y =h x in (if p y then y : (filterp ys) elsefilterp ys)

=

g x (filter p ys)

bei Wahl von

g x ys0 = let y =h x in (if p y then y :ys0 elseys0)

Folglich, mit genau diesemg:

filterp (map h l) = foldr g [ ] l

Wenig überraschend (?) entspricht diesesfoldr g [ ] in etwa dem schon zuvor hergeleitetenfilterMap p h.

(52)

Weniger Syntax — Mehr Struktur

Die Bedingung

filterp ((h x) :ys) = g x (filter p ys)

lässt sich weiter analysieren:

filterp ((h x) :ys)

=

let y =h x in (if p y then y : (filterp ys) elsefilterp ys)

=

g x (filterp ys)

bei Wahl von

g x ys0 = let y =h x in (if p y then y :ys0 elseys0)

Folglich, mit genau diesemg:

filterp (map h l) = foldr g [ ] l

Wenig überraschend (?) entspricht diesesfoldr g [ ] in etwa dem schon zuvor hergeleitetenfilterMap p h.

7

(53)

Weniger Syntax — Mehr Struktur

Die Bedingung

filterp ((h x) :ys) = g x (filter p ys)

lässt sich weiter analysieren:

filterp ((h x) :ys)

= let y =h x in (if p y then y : (filterp ys) elsefilterp ys)

=

g x (filterp ys)

bei Wahl von

g x ys0 = let y =h x in (if p y then y :ys0 elseys0)

Folglich, mit genau diesemg:

filterp (map h l) = foldr g [ ] l

Wenig überraschend (?) entspricht diesesfoldr g [ ] in etwa dem schon zuvor hergeleitetenfilterMap p h.

(54)

Weniger Syntax — Mehr Struktur

Die Bedingung

filterp ((h x) :ys) = g x (filter p ys)

lässt sich weiter analysieren:

filterp ((h x) :ys)

= let y =h x in (if p y then y : (filterp ys) elsefilterp ys)

= g x (filterp ys) bei Wahl von

g x ys0 = let y =h x in (if p y then y :ys0 elseys0)

Folglich, mit genau diesemg:

filterp (map h l) = foldr g [ ] l

Wenig überraschend (?) entspricht diesesfoldr g [ ] in etwa dem schon zuvor hergeleitetenfilterMap p h.

7

(55)

Weniger Syntax — Mehr Struktur

Die Bedingung

filterp ((h x) :ys) = g x (filter p ys)

lässt sich weiter analysieren:

filterp ((h x) :ys)

= let y =h x in (if p y then y : (filterp ys) elsefilterp ys)

= g x (filterp ys) bei Wahl von

g x ys0 = let y =h x in (if p y then y :ys0 elseys0)

Folglich, mit genau diesemg:

filterp (map h l) = foldr g [ ] l

Wenig überraschend (?) entspricht diesesfoldr g [ ] in etwa dem schon zuvor hergeleitetenfilterMap p h.

(56)

Weniger Syntax — Mehr Struktur

Die Bedingung

filterp ((h x) :ys) = g x (filter p ys)

lässt sich weiter analysieren:

filterp ((h x) :ys)

= let y =h x in (if p y then y : (filterp ys) elsefilterp ys)

= g x (filterp ys) bei Wahl von

g x ys0 = let y =h x in (if p y then y :ys0 elseys0)

Folglich, mit genau diesemg:

filterp (map h l) = foldr g [ ] l

Wenig überraschend (?) entspricht diesesfoldr g [ ]in etwa dem schon zuvor hergeleitetenfilterMap p h.

7

(57)

Problem: Zwischenergebnisse

Ein Beispiel:

filter((== 1)◦(‘mod‘3)) (map (ˆ2) [1..5])

= filter((== 1)◦(‘mod‘3)) (1: (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [2..5]))

= 1: (filter((== 1)◦(‘mod‘3)) (4: (map (ˆ2) [3..5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [3..5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (9: (map (ˆ2) [4,5])))

= 1:4: (filter((== 1)◦(‘mod‘3)) (map (ˆ2) [4,5]))

= 1:4: (filter((== 1)◦(‘mod‘3)) (16: (map (ˆ2) [5])))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [5]))

= 1:4:16: (filter((== 1)◦(‘mod‘3)) (25: (map (ˆ2) [ ])))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) (map(ˆ2) [ ]))

= 1:4:16:25: (filter((== 1)◦(‘mod‘3)) [ ] )

(58)

Short Cut Deforestation [Gill et al. 1993]

Schreibe Listenkonsumenten mittelsfoldr:

foldr f k ( : x1 :

x2 X : xn [ ]

) = f x1 f

x2 X

f xn k

Schreibe Listenerzeuger mittelsbuild:

build:: (∀β.(α→β→β)→β →β)→[α] build prod =prod (:) [ ]

9

(59)

Short Cut Deforestation [Gill et al. 1993]

Schreibe Listenkonsumenten mittelsfoldr:

foldr f k ( : x1 :

x2 X : xn [ ]

) = f x1 f

x2 X

f xn k

Schreibe Listenerzeuger mittelsbuild:

build:: (∀β.(α→β→β)→β →β)→[α]

build prod =prod (:) [ ]

(60)

Short Cut Deforestation [Gill et al. 1993]

Schreibe Listenkonsumenten mittelsfoldr:

foldr f k ( : x1 :

x2 X : xn [ ]

) = f x1 f

x2 X

f xn k

Schreibe Listenerzeuger mittelsbuild:

build:: (∀β.(α→β→β)→β →β)→[α]

build prod =prod (:) [ ]

9

(61)

Short Cut Deforestation [Gill et al. 1993]

Jedes derart polymorpheprod muss einer Funktion der folgenden Form entsprechen, für festen≥0 undx1, . . . ,xn:

prod = λf k → f x1 f

x2 X

f xn k

Zum Beispiel:

filter:: (α →Bool)→[α]→[α]

filterp l =build (λf k→let f0 x y |p x =f x y

|otherwise=y in foldr f0 k l)

(62)

Short Cut Deforestation [Gill et al. 1993]

Jedes derart polymorpheprod muss einer Funktion der folgenden Form entsprechen, für festen≥0 undx1, . . . ,xn:

prod = λf k → f x1 f

x2 X

f xn k

Zum Beispiel:

filter:: (α→Bool)→[α]→[α]

filterp l =build (λf k →let f0 x y |p x =f x y

|otherwise=y in foldr f0 k l)

10

(63)

Short Cut Deforestation [Gill et al. 1993]

Benutze folgende Regel:

foldrf k (build prod) prod f k

Zur Rechtfertigung:

Für den Compiler (GHC):

{−#RULES “foldr/build”

∀(prod ::∀β.(α→β →β)→β →β)f k. foldrf k (build prod) =prod f k #−}

(64)

Short Cut Deforestation [Gill et al. 1993]

Benutze folgende Regel:

foldr f0 k0 (build prod) prod f0 k0

Zur Rechtfertigung:

Für den Compiler (GHC):

{−#RULES “foldr/build”

∀(prod ::∀β.(α→β →β)→β →β)f k. foldrf k (build prod) =prod f k #−}

11

(65)

Short Cut Deforestation [Gill et al. 1993]

Benutze folgende Regel:

foldr f0 k0 (build prod) prod f0 k0 Zur Rechtfertigung:

foldr f0 k0 (buildprod)

Für den Compiler (GHC):

{−#RULES “foldr/build”

∀(prod ::∀β.(α→β →β)→β →β)f k. foldrf k (build prod) =prod f k #−}

(66)

Short Cut Deforestation [Gill et al. 1993]

Benutze folgende Regel:

foldr f0 k0 (build prod) prod f0 k0 Zur Rechtfertigung:

foldr f0 k0 (build (λf k → f x1 f

x2 X

f xn k

))

Für den Compiler (GHC):

{−#RULES “foldr/build”

∀(prod ::∀β.(α→β →β)→β →β)f k. foldrf k (build prod) =prod f k #−}

11

(67)

Short Cut Deforestation [Gill et al. 1993]

Benutze folgende Regel:

foldr f0 k0 (build prod) prod f0 k0 Zur Rechtfertigung:

foldrf0 k0 ( : x1 :

x2 X : xn [ ]

)

Für den Compiler (GHC):

{−#RULES “foldr/build”

∀(prod ::∀β.(α→β →β)→β →β)f k. foldrf k (build prod) =prod f k #−}

(68)

Short Cut Deforestation [Gill et al. 1993]

Benutze folgende Regel:

foldr f0 k0 (build prod) prod f0 k0

Zur Rechtfertigung:

f x1 f

x2 X

f xn k

Für den Compiler (GHC):

{−#RULES “foldr/build”

∀(prod ::∀β.(α→β →β)→β →β)f k. foldrf k (build prod) =prod f k #−}

11

(69)

Short Cut Deforestation [Gill et al. 1993]

Benutze folgende Regel:

foldr f0 k0 (build prod) prod f0 k0

Zur Rechtfertigung:

f x1 f

x2 X

f xn k

Für den Compiler (GHC):

{−#RULES “foldr/build”

(70)

Formaler Korrektheitsbeweis

Gegeben seiprod ::∀β.(τ →β→β)→β →β.

Dann:

(prod,prod)∈ ∀R.(idτ → R → R)→(R → R)

⇔ ∀R.∀(f1,f2)∈(idτ → R → R).∀(k1,k2)∈ R.

(prodτ1 f1 k1,prodτ2 f2 k2)∈ R

⇒ ((:),f2)∈(idτ →(foldr f2 k2)→(foldrf2 k2))

∧ ([ ],k2)∈(foldrf2 k2)

⇒ (prod[τ] (:) [ ],prodτ0 f2 k2)∈(foldr f2 k2)

⇔foldr f2 k2 (prod[τ] (:) [ ]) = prodτ0 f2 k2

⇔foldr f2 k2 (build prod) = prodτ0 f2 k2

für jede mögliche Wahl vonf2 ::τ →τ0→τ0 undk2 ::τ0.

12

(71)

Formaler Korrektheitsbeweis

Gegeben seiprod ::∀β.(τ →β→β)→β →β.

Dann:

(prod,prod)∈ ∀R.(idτ → R → R)→(R → R)

⇔ ∀R.∀(f1,f2)∈(idτ → R → R).∀(k1,k2)∈ R.

(prodτ1 f1 k1,prodτ2 f2 k2)∈ R

⇒ ((:),f2)∈(idτ →(foldr f2 k2)→(foldrf2 k2))

∧ ([ ],k2)∈(foldrf2 k2)

⇒ (prod[τ] (:) [ ],prodτ0 f2 k2)∈(foldr f2 k2)

⇔foldr f2 k2 (prod[τ] (:) [ ]) = prodτ0 f2 k2

⇔foldr f2 k2 (build prod) = prodτ0 f2 k2

für jede mögliche Wahl vonf2 ::τ →τ0→τ0 undk2 ::τ0.

(72)

Formaler Korrektheitsbeweis

Gegeben seiprod ::∀β.(τ →β→β)→β →β.

Dann:

(prod,prod)∈ ∀R.(idτ → R → R)→(R → R)

⇔ ∀R.∀(f1,f2)∈(idτ → R → R).∀(k1,k2)∈ R.

(prodτ1 f1 k1,prodτ2 f2 k2)∈ R wegen Definition von ∀R.F(R)und R → S

⇒ ((:),f2)∈(idτ →(foldr f2 k2)→(foldrf2 k2))

∧ ([ ],k2)∈(foldrf2 k2)

⇒ (prod[τ] (:) [ ],prodτ0 f2 k2)∈(foldr f2 k2)

⇔foldr f2 k2 (prod[τ] (:) [ ]) = prodτ0 f2 k2

⇔foldr f2 k2 (build prod) = prodτ0 f2 k2

für jede mögliche Wahl vonf2 ::τ →τ0→τ0 undk2 ::τ0.

12

(73)

Formaler Korrektheitsbeweis

Gegeben seiprod ::∀β.(τ →β→β)→β →β.

Dann:

(prod,prod)∈ ∀R.(idτ → R → R)→(R → R)

⇔∀R.∀(f1,f2)∈(idτ → R → R).∀(k1,k2)∈ R.

(prodτ1 f1 k1,prodτ2 f2 k2)∈ R

⇒ ((:),f2)∈(idτ →(foldr f2 k2)→(foldrf2 k2))

∧ ([ ],k2)∈(foldrf2 k2)

⇒ (prod[τ] (:) [ ],prodτ0 f2 k2)∈(foldrf2 k2)

durch Spezialisierung zu R=foldrf2 k2,f1= (:)und k1= [ ]

⇔foldr f2 k2 (prod[τ] (:) [ ]) = prodτ0 f2 k2

⇔foldr f2 k2 (build prod) = prodτ0 f2 k2

für jede mögliche Wahl vonf2 ::τ →τ0→τ0 undk2 ::τ0.

(74)

Formaler Korrektheitsbeweis

Gegeben seiprod ::∀β.(τ →β→β)→β →β.

Dann:

(prod,prod)∈ ∀R.(idτ → R → R)→(R → R)

⇔ ∀R.∀(f1,f2)∈(idτ → R → R).∀(k1,k2)∈ R.

(prodτ1 f1 k1,prodτ2 f2 k2)∈ R

⇒ ((:),f2)∈(idτ →(foldr f2 k2)→(foldrf2 k2))

∧ ([ ],k2)∈(foldrf2 k2)

⇒ (prod[τ] (:) [ ],prodτ0 f2 k2)∈(foldrf2 k2)

⇔foldr f2 k2 (prod[τ] (:) [ ]) = prodτ0 f2 k2 durch Vereinfachung

⇔foldr f2 k2 (build prod) = prodτ0 f2 k2

für jede mögliche Wahl vonf2 ::τ →τ0→τ0 undk2 ::τ0.

12

(75)

Formaler Korrektheitsbeweis

Gegeben seiprod ::∀β.(τ →β→β)→β →β.

Dann:

(prod,prod)∈ ∀R.(idτ → R → R)→(R → R)

⇔ ∀R.∀(f1,f2)∈(idτ → R → R).∀(k1,k2)∈ R.

(prodτ1 f1 k1,prodτ2 f2 k2)∈ R

⇒ ((:),f2)∈(idτ →(foldr f2 k2)→(foldrf2 k2))

∧ ([ ],k2)∈(foldrf2 k2)

⇒ (prod[τ] (:) [ ],prodτ0 f2 k2)∈(foldrf2 k2)

⇔foldr f2 k2 (prod[τ] (:) [ ]) = prodτ0 f2 k2

⇔foldr f2 k2 (build prod) = prodτ0 f2 k2 per Definition von build

für jede mögliche Wahl vonf2 ::τ →τ0→τ0 undk2 ::τ0.

(76)

Formaler Korrektheitsbeweis

Gegeben seiprod ::∀β.(τ →β→β)→β →β.

Dann:

(prod,prod)∈ ∀R.(idτ → R → R)→(R → R)

⇔ ∀R.∀(f1,f2)∈(idτ → R → R).∀(k1,k2)∈ R.

(prodτ1 f1 k1,prodτ2 f2 k2)∈ R

⇒ ((:),f2)∈(idτ →(foldr f2 k2)→(foldrf2 k2))

∧ ([ ],k2)∈(foldrf2 k2)

⇒ (prod[τ] (:) [ ],prodτ0 f2 k2)∈(foldrf2 k2)

⇔foldr f2 k2 (prod[τ] (:) [ ]) = prodτ0 f2 k2

⇔foldr f2 k2 (build prod) = prodτ0 f2 k2

für jede mögliche Wahl vonf2 ::τ →τ0→τ0 undk2 ::τ0.

12

(77)

Anwendung am Beispiel

Funktionen mittelsfoldr undbuild schreiben:

filter:: (α→Bool)→[α]→[α]

filterp l =build (λf k →let f0 x y |p x =f x y

|otherwise=y in foldr f0 k l)

map:: (α→β)→[α]→[β]

map h l =build (λf k →foldr(λx y →f (h x) y) k l)

Dann:

filterp (map h l)

= build(λf k →

letf0 · · ·=· · · in foldrf0 k

(build (λf k →foldr(λx y →f (h x) y) k l)))

= build(λf k →

letf0 · · ·=· · ·

in foldr(λx y →f0 (h x) y) k l)

Referenzen

ÄHNLICHE DOKUMENTE

• Rekursive Funktionen können so nicht definiert werden, denn ohne Namen kann eine Funktion nicht in ihrem Rumpf.

• Die Tiefe eines Baums ist die maximale Anzahl innerer Knoten auf einem Pfad von der Wurzel zu einem Blatt. • Ein vollständiger balancierter Binärbaum mit n = 2 k Blättern hat Tiefe

• Rekursive Funktionen können so nicht definiert werden, denn ohne Namen kann eine Funktion nicht in ihrem Rumpf.

• sp¨ater per Induktion ¨uber die Syntax beweisen, dass jede Funktion die semantischen Einschr¨ankungen ihres Typs erf¨ullt.. (semantisch, nicht syntaktisch) von Elementen diesen

• sp¨ater per Induktion ¨uber die Syntax beweisen, dass jede Funktion die semantischen Einschr¨ankungen ihres Typs

• Beweisprinzip für polymorphe Funktionen auf Listen. • Optimierung durch

Hier eignet sich LISP sehr gut, weshalb LISP auch als eine Sprache der künstlichen Intelligenz (KI) charakterisiert wurde. Es charakterisiert die Sprache LISP, dass nicht

Neben dem bisher beschriebenen strukturellen Aspekt, ist der operationale Aspekt f¨ur ei- ne ausgewogene Anfrageverarbeitung ebenfalls ein zentraler Baustein, da physische