• Keine Ergebnisse gefunden

zip :: [ a ] -> [ b ] -> [ ( a, b ) ] zip ( x : xs ) ( y : ys ) = ( x, y ) : zip ( xs ) ( ys ) zip = []

N/A
N/A
Protected

Academic year: 2022

Aktie "zip :: [ a ] -> [ b ] -> [ ( a, b ) ] zip ( x : xs ) ( y : ys ) = ( x, y ) : zip ( xs ) ( ys ) zip = []"

Copied!
16
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Was bisher geschah

Funktionale Programmierung in Haskell:

I Algebraische Datentypen

I Pattern Matching

I Polymorphie

I Typklassen

I Rekursive Datentypen: Peano-Zahlen, Listen, Bäume

I Rekursive Funktionen

I strukturelle Induktion

I Rekursionsschemata für Peano-Zahlen, Listen, Bäume

I Funktionen höherer Ordnung (mit Funktionen als Argumenten)

I λ-Kalkül,β-Reduktion

I foldauf rekursiven Datentypen (Peano-Zahlen, Listen, Bäume)

I mapauf Listen und Bäumen,filterauf Listen

(2)

Nützliche Funktionen

take :: Int -> [ a ] -> [ a ] take 0 _ = []

take _ [] = []

take n ( x : xs ) = x : ( take ( n - 1 ) xs ) take 3 [ 1 .. 10 ]

takeWhile :: ( a -> Bool ) -> [ a ] -> [ a ] takeWhile p xs = case xs of

[] -> []

x : xss -> if p x

then x : ( take While p xss ) else []

takeWhile ( \ x -> mod x 5 < 4) [ 1 .. 10 ] dropWhile :: ( a -> Bool ) -> [ a ] -> [ a ] dropWhile p xs = case xs of

[] -> []

x : xss -> if p x

then ( dropWhile p xss ) else xss

dropWhile ( < 4 ) [ 1 .. 10 ]

(3)

Nützliche Funktionen

zip :: [ a ] -> [ b ] -> [ ( a , b ) ] zip ( x : xs ) ( y : ys )

= ( x, y ) : zip ( xs ) ( ys ) zip _ _ = []

zip "foo" [1 .. 5]

zipWith :: ( a -> b -> c )

-> [ a ] -> [ b ] -> [ c ]

zipWith f xs ys = map ( \ ( x, y ) -> f x y ) ( zip xs ys )

zipWith (+) [ 1 .. 10 ] [ 2, 4 .. 10 ]

zipWith (\x y -> ( foldr (\ _ y -> 1 + y) 0 x) + y) [ "foo", "b", "ar" ] [ 1 .. 10 ]

(4)

Wiederholung – Auswertung von Ausdrücken

Reduktion: Termersetzung durch Funktionsanwendung Redex: reduzierbarer Teilterm

Normalform: nicht-reduzierbarer Ausdruck (Ausdruck ohne Redex)

Auswertung: schrittweise Reduktion, bis Normalform erreicht

square :: Int -> Int square x = x * x 2 Möglichkeiten,

den Wert vonsquare (3 + 1)zu berechnen

Es wird bei beiden Möglichkeiten derselbe Wert berechnet.

(Haskell ist nebenwirkungsfrei.)

(5)

Auswertungsreihenfolge

mult :: Int -> Int -> Int mult = \x y -> x * y Redexe von

mult ( 1 + 2 ) ( 2 + 3 )

data N = Z | S N

nichtnull :: N -> Bool nichtnull n = case n of

Z -> False S _ -> True Redexe von

nichtnull ( S undefined )

(6)

Auswertungs-Strategien

innermost Reduktion von Redexen, die keinen Redex enthalten

(Parameterübergabe by value)

outermost Reduktion von Redexen, die in keinem Redex enthalten sind

(Parameterübergabe by name) (jeweils so weit links wie möglich zuerst) square :: Int -> Int

square x = x * x

square (3 + 1)

Teilterme inλ-Ausdrücken werden nicht reduziert.

(\ x -> 1 + 2) 1

(7)

Termination

inf :: Int inf = 1 + inf

fst :: ( a , b ) -> a fst ( x, y ) = x Auswertung von fst (3, inf)

terminiert unter outermost-Strategie, aber nicht unter innermost-Strategie Satz

Für jeden Ausdruck, für den die Auswertung unter irgendeiner Strategie terminiert, terminert auch die Auswertung unter outermost-Strategie.

(8)

Unendliche Datenstrukturen

nats_from :: Int -> [ Int ]

nats_from n = n : ( nats_from ( n + 1 ) )

nats_from 3

outermost-Auswertung von

head ( tail ( tail ( nats_from 3 ) )

= head ( tail ( tail ( 3 : ( nats_from ( 3 + 1 )))))

= head ( tail ( nats_from (3 + 1)))

= head ( tail ( (3 + 1) : nats_from (( 3 + 1 ) + 1 ))

= head ( nats_from ( ( 3 + 1 ) + 1 ))

= head (((3 + 1) + 1) : nats_from (((3 + 1) + 1) + 1))

= ( 3 + 1 ) + 1

= 4 + 1

= 5

(9)

Lazyness

I jeder Wert wird erst bei Bedarf ausgewertet.

I Listen sind Streams, der Tail wird erst bei Bedarf ausgewertet.

I Wann die Auswertung stattfindet, lässt sich nicht beobachten.

Die Auswertung hat keine Nebenwirkungen.

(10)

Strictness

zu jedem TypT betrachteT={⊥} ∪T dabei ist⊥ein „Nicht-Resultat vom TypT“

I Exceptionundefined :: T

I oder Nicht-Terminationlet { x = x } in x Definition:

Funktionf heißtstrikt, wennf(⊥) =⊥.

Funktionf mitnArgumenten heißtstrikt ini, falls (xi =⊥)⇒f(x1, . . . ,xn) =⊥

in Haskell:

I Konstruktoren (Cons,. . . ) sind nicht strikt,

I Destruktoren (head, tail,. . . ) sind strikt.

(11)

Strictness – Beispiele

I length :: [a] -> Intist strikt:

length undefined ==> exception

I (:) :: a->[a]->[a]ist nicht strikt im 1. Argument:

length (undefined : [2,3]) ==> 3 d.h. (undefined : [2,3]) ist nicht⊥

I (&&)ist strikt im 1. Argument, nicht strikt im 2. Argument

undefined && True ==> (exception) False && undefined ==> False

(12)

Lazy Evaluation – Realisierung

Begriffe:

nicht strikt : nicht zu früh auswerten lazy : höchstens einmal auswerten bei jedem Konstruktor- und Funktionsaufruf:

I kehrtsofortzurück

I Resultat istthunk

I thunk wird erst bei Bedarf ausgewertet

I Bedarf entsteht durch Pattern Matching

I nach Auswertung: thunk durch Resultat überschreiben Lazy Evaluation (Bedarfsauswertung) =

Outermost-Reduktionsstrategie mit Sharing

(13)

Unendliche Datenstrukturen

inf :: Int inf = 1 + inf fst(3, inf) einsen :: [Int]

einsen = 1 : einsen head einsen

take 3 einsen walzer :: [Int]

walzer = 1 : 2 : 3 : walzer nats :: [Int]

nats = 0 : map (+1) nats takeWhile (<= 5) nats

ListeallerQuadratzahlen? Primzahlen?

(14)

Motivation: Datenströme

Folge von Daten:

I erzeugen (producer)

I transformieren

I verarbeiten (consumer)

aus softwaretechnischen Gründen:

diese drei Aspekteim Programmtext trennen, aus Effizienzgründen:

in der Ausführung verschränken

(bedarfsgesteuerte Transformation/Erzeugung)

(15)

Rekursive Stream-Definitionen

nats = 0 : map (+1) nats fibonacci = 0

: 1

: zipWith (+) fibonacci ( tail fibonacci ) take 10 fibonacci

take 1 $ dropWhile (< 200) fibonacci Welchen Wert hatbin?

bin = False : True

: concat ( map ( \ x -> [ x, not x ] ) ( tail bin ) )

Thue-Morse-Folget =0110100110010110. . . mit vielen interessanten Eigenschaften, z.B.

I t :=limn→∞τn(0)fürτ:07→01,17→10

I t ist kubikfrei

I Abstandsfolgev :=210201210120. . .

ist auch Fixpunkt eines Morphismus, quadratfrei

(16)

Primzahlen

Sieb des Eratosthenes

nats_from :: Int -> [ Int ]

nats_from n = n : nats_from ( n + 1 ) primzahlen :: [ Int ]

primzahlen = sieb $ nats_from 2 sieb :: [ Int ] -> [ Int ] sieb (x : xs) = ...

take 100 primzahlen

takeWhile (< 100) primzahlen

Referenzen

ÄHNLICHE DOKUMENTE

Die Classic Armatur ist in verschiedenen Ausführungen z. für gefiltertes, ochendes und gekühltes Trink- wasser – mit oder ohne Kohlensäure – erhältlich. &gt;

In this section we consider a certain type of algebraic variety with an action of a reductive group G whose orbit structure is closely related to the structure of the E Z -orbits in

The main tool we use to deduce our results is the following: For each w ∈ W , the Bruhat cell P 0 wP is Z-invariant, and we show that the orbits in P 0 wP correspond to the orbits in

Return of the exercise sheet: 03.Oct.2019 during the exercise

Depending on the selected textile and the fabric openness coefficient (0 to 14 %), the system meets all the requirements of modern sun shading, from an opaque fabric featuring

Der Schirm gerät in eine NegativkuZippere, die beim TWIX durch sofortiges Nachgeben der Bremsleine in der KuZippereninnenseite behoben werden kann.. Bei andauerndem Trudeln

Für den Betrieb des Wassersystems Zip HydroTap ® G4 CS benötigen Sie eine passende Armatur, zum Beispiel die Armatur »Classic CS«. Die Montage- und Gebrauchsanleitung ist bei

Unter „Dominierende Farbe“ können Sie festlegen, welche Farbe die gesuchten Bilder in erster Linie enthalten sollen. Diese wird anhand von Durchschnittswerten des