Rekursionen - Informatik

Werbung
Das ist eine
Signatur
Die Signatur der Funktionen f
=> f :: Int -> Int -> Int
Wenn nicht explizit angegeben dann ist der Typkonstruktor rechtsassoziativ geklammert (man hat
sich darauf geeinigt da man in der Praxis häufiger rechtsassoziative Typkonstruktoren verwendet als
Linksassoziative )
d.h: f :: Int -> Int -> Int entspricht => f :: (Int -> (Int -> Int))
anonyme Funktion : (\n -> (add 2) n)
length :: [a] -> Int
a in der Typsignatur von length heißt Typvariable. Typvariablen werden
gewöhnlich mit Kleinbuchstaben vom Anfang des Alphabets bezeichnet: a, b, c ,…
Typdefinition:
Z.b.:
Tree a =
definierende
Typvariable
angewandte
Nil |
Typvariable
Leaf a
Node a (Tree a) (Tree a)
Wichtige Signaturen:
(man sollte auch wissen was diese Funktionen machen und wie man sie verwendet)
filter :: (a -> Bool) -> [a] -> [a]
map :: (a -> b) -> [a] -> [b]
foldl :: (a -> b -> a) -> a -> [b] -> a
add :: Int -> (Int -> Int)
add m n = m+n
add’ :: (Int,Int) -> Int
add’ (m,n) = m+n
Sprechweise: Die Funktion...
• add ist curryfiziert
• add’ ist uncurryfiziert
curry :: ((a,b) -> c) -> (a -> b -> c)
curry f x y = f (x,y)
uncurry :: (a -> b -> c) -> ((a,b) -> c)
uncurry g (x,y) = g x y
• Curryfizieren ersetzt Produkt-/Tupelbildung “×” durch
Funktionspfeil “->”.
• Decurryfizieren ersetzt Funktionspfeil “ ->!” durch
Produkt- /Tupelbildung “×”.
• (Parametrische) Polymorphie ... gleicher Code trotz unterschiedlicher Typen
• ad-hoc Polymorphie (synonym: Überladen (engl. Overloading))... unterschiedlicher Code trotz
gleichen Namens (mit sinnvollerweise i.a. ähnlicher Funktionalität)
Rekursionen:
Generell: eine Rechenvorschrift heißt rekursiv, wenn sie in ihrem Rumpf (direkt oder indirekt)
aufgerufen wird.
 Schlichte (repetitive)
z.b.: ggt (größter gemeinsamer Teiler)
 lineare
z.b.: fac (Fakultätsfunktion)
 geschachtelte
z.b.: fun91 (Funktion aus der Vorlesung)
 baumartige kaskadenartige
z.b.: fib (Fibonacci -Zahlen)
 Indirekte oder auch verschränkte (wechselweise) zwei oder mehr Funktionen rufen sich
wechselweise auf
z.b.: even u. odd
Algebraische Typen:
 Summentypen (Verkehrsmittel)
o Aufzählungstypen (Jahreszeiten, Boolesche Werte) ein oder mehrere Konstruktoren,
alle nullstellig
o Produkttypen
(Person) nur ein Konstruktor, mehrstellig
 Rekursive Typen
 Polymorphe Typen
Nullstellige Konstruktoren führen zu Aufzählungstypen.
(Alternativenlose) mehrstellige Konstruktoren führen auf Produkttypen.
Mehrere (null- oder mehrstellige) Konstruktoren führen auf Summentypen.
newtype-Deklarationen sind auf Typen mit nur einem Konstruktor eingeschränkt. Ist bei der
Implementierung so Effizienz wie Type , und bei der Übersetzung so Typsicherheit wie Data.
Unbedingt zu beachten ist – type führt neue Namen für bereits existierende Typen
ein (Typsynonyme!), keine neuen Typen. Durch type-Deklarationen eingeführte Typsyonyme
• tragen zur Dokumentation bei und • erleichtern (i.a.) das Programmverständnis
aber...• führen nicht zu (zusätzlicher) Typsicherheit!
Eine Typklasse ist eine Kollektion von Typen, auf denen eine in der Typklasse festgelegte Menge
von Funktionen definiert ist. (zB.: Eq, Ord , Num)
class Size a where
-- Definition der Typklasse Size
size :: a -> Int
instance Size (Tree a) where
-- Instanzbildung fuer (Tree a)
size Nil = 0
size (Node n l r) = 1 + size l + size r
Tree a ist eine Instanz der (gehört zur) Typklasse Size, wenn a zu dieser
Klasse gehört.
Intuitiv ersetzt die Angabe der deriving-Klausel (automatische Erstellung) die Angabe einer
instance-Klausel (manuelle Erstellung).
Funktionen, unter deren Argumenten oder Resultaten Funktionen sind, heißen Funktionen höherer
Ordnung oder kurz Funktionale. Mithin... Funktionale sind spezielle Funktionen!
Des Pudels Kern ...bei Funktionalen ist die => Wiederverwendung!
Monaden (sind Konstruktorklassen) erlauben die Reihenfolge, in der Operationen ausgeführt
werden, explizit festzulegen.
Konstruktorklassen haben Typkonstruktoren als Elemente.Typkonstruktoren sind Funktionen, die
aus gegebenen Typen neue Typen erzeugen (Bsp:Tupelkonstruktor ( ), Listenkonstruktor[ ]
Auswertungsstrategien:
applicative order (leftmost-innermost)
normal order (leftmost-outermost)
Von Normal Order zu Lazy Evaluation (call-by-need) über Graphentransformation -> Ziel:
Vermeidung von Mehrfachauswertungen zur Effizienzsteigerung, garantiert, dass Argumente
höchstens einmal (möglicherweise also gar nicht) ausgewertet werden.
Lambda Kalkül (Alonzo Church (1936))
Reiner
Angewandter
(syntaktisch angereichert,
praxisnäher))
ist ein spezielles formales Berechnungsmodell,
wie viele andere auch
Der Lambda Kalkül ist ausgezeichnet durch nur wenige syntaktische Konstrukte, einfache Semantik
und der Lambda Kalkül ist Turing-mächtig, da alle “intuitiv berechenbaren” Funktionen im -Kalkül
ausdrückbar sind.
Die Menge Exp der Ausdrücke des (reinen) l-Kalküls, kurz
Lambda Ausdruck ist definiert durch: Name, Abstraktion, Applikation
Lambda Konversionen:
Alpha Konversion (Umbenennung formaler Parameter)
Beta Konversion (Funktionsanwendung)
Eta Konversion (Elimination redundanter Funktion)
Theorem1:wenn eine Normalform existiert, dann ist sie eindeutig (bis auf Alpha Konversion)!
Theorem2:normal order Reduktion terminiert am häufigsten!
Ein -Ausdruck ist in Normalform, wenn er durch -Reduktion und -Reduktion nicht weiter
reduzierbar ist.
Herunterladen