ProMo01: Einführung - Theoretische Informatik

Werbung
Organisation Grundlagen Haskell GHC Typen Funktionen
Programmierung und Modellierung
mit Haskell
Einführung
Martin Hofmann
Steffen Jost
LFE Theoretische Informatik, Institut für Informatik,
Ludwig-Maximilians Universität, München
7. April 2014
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-1
Organisation Grundlagen Haskell GHC Typen Funktionen
Organisation
Vorlesung
Anmeldung zur Vorlesung per UniworX zwingend
Umfang: 3 SWS, d.h. einige Vorlesungstermine entfallen;
Newsfeed der Vorlesungshomepage beachten!
https://www.tcs.ifi.lmu.de/lehre/ss-2014/promo/promo
Übungen
Teilnahme freiwillig, aber empfehlenswert
UniworX Anmeldung zur Übungsgruppe zwingend
Hausübung bringen prozentual Bonuspunkte zur Klausur
x% Hausübung bringen x% des Bonus;
Bonus entscheidet nicht über bestehen
Beginn der Übung in 2. Semesterwoche
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-2
Organisation Grundlagen Haskell GHC Typen Funktionen
Inhalt der Vorlesung
Progammierung und Modellierung
Funktionsbegriff, Basistypen
Listen, Pattern Matching
Rekursion und Terminierung
Induktion & Korrektheitsbeweise
Benutzerdefinierte Datentypen
Tiefen- & Breitensuche
Laufzeitbetrachtungen
Polymorphie, Typklassen und Module
Funktionen höherer Ordnung
Typisierung & Typinferenz
IO, Monaden & Funktoren
Verzögerte Auswertung
Semantik
Parallele Auswertung
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-3
Organisation Grundlagen Haskell GHC Typen Funktionen
Literatur
Die Vorlesung richtet sich nach folgenden Quellen:
Buch/Online
Programming in Haskell by Graham Hutton
B
Learn You a Haskell for Great Good! by Miran Lipovača B O
A Gentle Introduction To Haskell by Paul Hudak, John
O
Peterson, Joseph Fasel
Real World Haskell by Bryan O’Sullivan, Don Stewart, B O
John Goerzen
School of Haskell by FPComplete
O
Haskell Wiki
O
so wie ältere Skripte des Lehrstuhls TCS
Links/ISBN der Quellen, Skript ⇒ Vorlesungshomepage
Weitere wichtige Online-Quelle: www.haskell.org
Haskell-Platform: GHC Kompiler & Interpreter,
Dokumentation der Standardbibliotheken, Hoogle
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-4
Organisation Grundlagen Haskell GHC Typen Funktionen
Was ist Informatik?
Von franz. informatique (= information + mathématiques).
Engl.: computer science, auch informatics.
DUDEN Informatik: Wissenschaft von der systematischen
Verarbeitung von Informationen, besonders der automatischen
Verarbeitung mit Computern.
Gesellschaft f. Inf. (GI): Wissenschaft, Technik und
Anwendung der maschinellen Verarbeitung und Übermittlung
von Informationen.
Association vor Computing Machinery (ACM): Systematic
study of algorithms and data structures.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-5
Organisation Grundlagen Haskell GHC Typen Funktionen
Teilbereiche der Informatik
Technische Informatik
Aufbau und Wirkungsweise von Computern
Praktische Informatik
Konstruktion von Informationsverarbeitungssystemen sowie
deren Realisierung auf Computern
Theoretische Informatik
Theoretische und verallgemeinerte Behandlungen von Fragen
und Konzepten der Informatik
Angewandte Informatik
Verbindung von Informatik mit anderen Wissenschaften
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-6
Organisation Grundlagen Haskell GHC Typen Funktionen
Typische Arbeitsgebiete
Algorithmen und Komplexität
Betriebssysteme
Bioinformatik
Datenbanken
Grafik
Medieninformatik
Programmiersprachen und Compiler
Rechnerarchitektur und Rechnernetze
Robotik
Simulation
Softwareentwicklung
Spezifikation, Verifikation, Modellierung
Wirtschaftsinformatik
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-7
Organisation Grundlagen Haskell GHC Typen Funktionen
Imperativ vs. Deklarativ
Imperative Sprachen (Assembler, C, Java, etc.) orientieren sich an
den Fähigkeiten der Maschine. Programmierung wird durch
Abstraktion vieler Einzelschritte vereinfacht (z.B. Schleifen).
Funktionale Programmierung ist dagegen deklarativ:
Spezifiziere was berechnet werden soll,
nicht wie es berechnet wird!
Charakteristische Eigenschaft deklarativer Sprachen ist die
Church-Rosser Eigenschaft:
Die Reihenfolge der Auswertung ist unerheblich für das
Ergebnis der Berechnung ist.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-8
Organisation Grundlagen Haskell GHC Typen Funktionen
Imperativ vs. Deklarativ
Imperative Sprachen (Assembler, C, Java, etc.) orientieren sich an
den Fähigkeiten der Maschine. Programmierung wird durch
Abstraktion vieler Einzelschritte vereinfacht (z.B. Schleifen).
Funktionale Programmierung ist dagegen deklarativ:
Spezifiziere was berechnet werden soll,
nicht wie es berechnet wird!
Charakteristische Eigenschaft deklarativer Sprachen ist die
Church-Rosser Eigenschaft:
Die Reihenfolge der Auswertung ist unerheblich für das
Ergebnis der Berechnung ist.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-8
Organisation Grundlagen Haskell GHC Typen Funktionen
Imperativ vs. Deklarativ
Deklarative Sprachen sind fast immer durch die Sprache der
Mathematik motiviert:
Prädikaten-Logik
Relationale Algebra
λ-Kalkül
⇒
⇒
⇒
Prolog
SQL
Haskell
Rein deklarative Sprachen in der Praxis jedoch oft problematisch,
da der Ressourcenverbrauch eines Programmes (Speicherplatz,
Zeit, etc.) kritisch vom wie abhängt.
(Prolog, SQL ohne join).
Funktionale Programmierung geht einen Mittelweg:
Die Berechnung bleibt deterministisch
wir kümmern uns nur nicht so sehr darum
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-9
Organisation Grundlagen Haskell GHC Typen Funktionen
Imperativ vs. Deklarativ
Deklarative Sprachen sind fast immer durch die Sprache der
Mathematik motiviert:
Prädikaten-Logik
Relationale Algebra
λ-Kalkül
⇒
⇒
⇒
Prolog
SQL
Haskell
Rein deklarative Sprachen in der Praxis jedoch oft problematisch,
da der Ressourcenverbrauch eines Programmes (Speicherplatz,
Zeit, etc.) kritisch vom wie abhängt.
(Prolog, SQL ohne join).
Funktionale Programmierung geht einen Mittelweg:
Die Berechnung bleibt deterministisch
wir kümmern uns nur nicht so sehr darum
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-9
Organisation Grundlagen Haskell GHC Typen Funktionen
Referentielle Transparenz
Wichtige Eigenschaft deklarativer Sprachen:
Referentielle Transparenz
Wert einer Variablen ist unveränderlich
Aufrufe mit gleichen Argumenten liefern gleiches Ergebnis
Keine Seiteneffekte!
Konsequenzen:
Programme lokal verständlich und kompositional
Testen/Verifikation reduziert sich auf Gleichheitsschließen
Kompiler kann sehr aggressiv optimieren
Parallele Berechnung einfacher
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-10
Organisation Grundlagen Haskell GHC Typen Funktionen
Vor-/Nachteile Funktionaler Programm.
FP ist alt, doch kaum verbreitet?!
λ-Kalkül 1930s, Lisp 1958
Völlig andere (mathematische) Denkweise
Verlust von “Kontrolle” gegenüber herkömmlichen Sprachen,
Maschinen-nahe Hand-Optimierung schwierig durchführbar
Geringe kommerzielle Unterstützung
IDE, Debugger,. . .
Kompiler “meckert viel” bevor man testen kann
Aber:
“Well-typed programs can’t go wrong!”, R.Milner
Gut geeignet für Programmanalyse
“Einschränkungen” vorteilhaft für Mehrpersonen-Projekte
Kurzer Code ⇒ kurze Entwicklungszeit; Wartbarkeit
Funktionale Merkmale inzwischen in vielen anderen Sprachen
z.B. Funktionen höherer Ordnung, Anonyme Funktionen,
Java GC optimiert auf kurzlebige, statische Objekte, etc.
Neues kommerzielle Interesse wegen Multi-Cores
“The Downfall of Imperative Programming”, Milewski
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-11
Organisation Grundlagen Haskell GHC Typen Funktionen
Vor-/Nachteile Funktionaler Programm.
FP ist alt, doch kaum verbreitet?!
λ-Kalkül 1930s, Lisp 1958
Völlig andere (mathematische) Denkweise
Verlust von “Kontrolle” gegenüber herkömmlichen Sprachen,
Maschinen-nahe Hand-Optimierung schwierig durchführbar
Geringe kommerzielle Unterstützung
IDE, Debugger,. . .
Kompiler “meckert viel” bevor man testen kann
Aber:
“Well-typed programs can’t go wrong!”, R.Milner
Gut geeignet für Programmanalyse
“Einschränkungen” vorteilhaft für Mehrpersonen-Projekte
Kurzer Code ⇒ kurze Entwicklungszeit; Wartbarkeit
Funktionale Merkmale inzwischen in vielen anderen Sprachen
z.B. Funktionen höherer Ordnung, Anonyme Funktionen,
Java GC optimiert auf kurzlebige, statische Objekte, etc.
Neues kommerzielle Interesse wegen Multi-Cores
“The Downfall of Imperative Programming”, Milewski
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-11
Organisation Grundlagen Haskell GHC Typen Funktionen
Vor-/Nachteile Funktionaler Programm.
FP ist alt, doch kaum verbreitet?!
λ-Kalkül 1930s, Lisp 1958
Völlig andere (mathematische) Denkweise
Verlust von “Kontrolle” gegenüber herkömmlichen Sprachen,
Maschinen-nahe Hand-Optimierung schwierig durchführbar
Geringe kommerzielle Unterstützung
IDE, Debugger,. . .
Kompiler “meckert viel” bevor man testen kann
Aber:
“Well-typed programs can’t go wrong!”, R.Milner
Gut geeignet für Programmanalyse
“Einschränkungen” vorteilhaft für Mehrpersonen-Projekte
Kurzer Code ⇒ kurze Entwicklungszeit; Wartbarkeit
Funktionale Merkmale inzwischen in vielen anderen Sprachen
z.B. Funktionen höherer Ordnung, Anonyme Funktionen,
Java GC optimiert auf kurzlebige, statische Objekte, etc.
Neues kommerzielle Interesse wegen Multi-Cores
“The Downfall of Imperative Programming”, Milewski
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-11
Organisation Grundlagen Haskell GHC Typen Funktionen
Haskell
Effektfreie funktionale Sprache mit verzögerter Auswertung
für universellen Einsatz
Benannt nach Haskell Curry (1900-82), Logiker
Standards: Haskell98 und Haskell2010
Viele verschiedene Implementierung verfügbar; wichtigste ist
die Haskell Platform mit “batteries included”:
Kompiler, Interpreter und zahlreichen Bibliotheken
GHC : Glasgow/Glorious Haskell Compiler
Hammond, 1989
akutelle Versionen mehrmals pro Jahr
Hauptentwickler erhielten 2011 ACM SIGPLAN Programming
Languages Software Award:
Simon Peyton-Jones
Microsoft Research Cambridge
Simon Marlow
Facebook
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-12
Organisation Grundlagen Haskell GHC Typen Funktionen
Warum gerade Haskell?
Für einen großen Teil der Vorlesungsinhalte spielt es keine Rolle,
welche funktionale Sprache wir betrachten.
Haskell ist im Gegensatz zu vielen anderen funktionalen
Sprachen (z.B. SML) rein funktional, d.h. referentielle
Transparenz gilt uneingeschränkt
Haskell hat ein starkes statisches Typsystem
Viel aktuelle Dokumentation verfügbar
Kommerzielle Unterstützung
IDE auf fpcomplete.com
Arithmetik mit beliebiger Präzision verfügbar
Gute Unterstützung für Parallelität
Produziert “flotten” Code
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-13
Organisation Grundlagen Haskell GHC Typen Funktionen
GHC
In der Vorlesung arbeiten wir mit der Haskell Platform, welche
aus GHC, Bibliotheken und Dokumentation besteht. Die meiste
Dokumentation ist aber auch online verfügbar, wie zum Beispiel
http://www.haskell.org/ghc/docs/latest/html/libraries/
Glasgow Haskell Kompiler (GHC) kennt zwei Arbeitsweisen:
GHC Normaler Kompiler. Ein Programm wird in mehreren
Dateien geschrieben und mithilfe des GHC in ein
ausführbares Programm übersetzt.
GHCi Interpreter Modus: Man gibt Definitionen ein und
GHCI wertet diese sofort aus und zeigt den Wert an.
Wir befassen uns zunächst primär mit dem interaktiven Modus.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-14
Organisation Grundlagen Haskell GHC Typen Funktionen
GHCI
> ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> 1 + 2
3
Prelude> 3 + 4 * 5
23
Prelude> (3 + 4) * 5
35
Prelude>
Der Text hinter dem Prompt Prelude> wurde vom Benutzer
getätigt, alles andere sind Ausgaben von GHCi. Der Prompt gibt
Martin
Hofmann, Steffen
Jost
Programmierung
und Modellierung
per Default alle
geladenen
Bibliotheken
(Module)
an.
01-15
Organisation Grundlagen Haskell GHC Typen Funktionen
GHCI
> ghci +RTS -M1g
GHCi, version 7.6.3: http://www.haskell.org/ghc/
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> 1 + 2
3
Prelude> 3 + 4 * 5
23
Prelude> (3 + 4) * 5
35
Prelude>
Der Text hinter dem Prompt Prelude> wurde vom Benutzer
getätigt, alles andere sind Ausgaben von GHCi. Der Prompt gibt
Martin
Hofmann, Steffen
Jost
Programmierung
und Modellierung
per Default alle
geladenen
Bibliotheken
(Module)
an.
01-15
Organisation Grundlagen Haskell GHC Typen Funktionen
GHCI
Der Interpreter wertet alle eingegebenen Ausdrücke aus. Mit den
Pfeiltasten kann von vorherige Eingaben durchblättern
Zur Steuerung des Interpreters stehen Befehle zur Verfügung,
welche alle mit einem Doppelpunkt beginnen, z.B. :? für die Hilfe.
Alle Befehle kann man abkürzen. So kann man den Interpreter
sowohl mit :quit also auch mit :q verlassen. Für uneindeutige
Abkürzungen gibt es voreingestellte Defaults.
Auch für GHCi macht es Sinn, Programmdefinitionen mit einem
gewöhnlichen Texteditor in eine separate Datei speichern und dann
in den Interpreter zu laden, um nicht immer alles neu eintippen zu
müssen.
:l datei .hs -- lade Definition aus Datei datei .hs
:r
-- erneut alle offenen Dateien einlesen
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-16
Organisation Grundlagen Haskell GHC Typen Funktionen
Fallstricke
Haskell beachtet Groß-/Kleinschreibung!
Haskell ist “whitespace”-sensitiv: Veränderungen an Leerzeichen,
Tabulatoren und Zeilenumbruch können Fehler verursachen!
Grundsätzlich gilt:
Beginnt die nächste Zeile in . . .
Spalte weiter rechts: vorheriger Zeile geht weiter
gleicher Spalte: nächstes Element eines Blocks beginnt
Spalte weiter links: Block beendet
Daraus folgt:
Alle Top-level Definition müssen in gleicher Spalte beginnen
Einrückung kann viele Klammern sparen
Tabulatorweite in Editor und GHC muss übereinstimmen
Anstatt Einrückung können auch { } und ; benutzt werden.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-17
Organisation Grundlagen Haskell GHC Typen Funktionen
Ausdrücke & Werte
GHCi wertet Ausdrücke aus. Ein Ausdruck kann
atomar sein, wie z.B. 1337, ’a’
zusammengesetzt sein, wie z.B. 12+1, 27 * (7 + 5)
Ein Ausdruck kann also aus mehreren Unterausdrücken bestehen.
Mit Klammern können wir explizit angeben, in welcher Reihenfolge
ein Ausdruck aus seinen Unterausdrücken zusammengesetzt ist.
Ein Ausdruck hat (meistens) auch einen Wert; so ist 13 der Wert
des Ausdrucks 12+1.
Jeder korrekt gebildete Ausdruck besitzt einen Typ.
Zum Beispiel: der Ausdruck 12+1 hat den Typ Int.
Wir schreiben kurz 12+1 :: Int
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-18
Organisation Grundlagen Haskell GHC Typen Funktionen
Einfache Typen Zusammengesetze Typen
Typen
Ein Typ ist eine Menge von Werten; so bezeichnet der Typ Int
meistens die Menge der ganzen Zahlen von −229 bis 229 − 1.
Haskell-Syntax:
Typnamen beginnen immer mit Großbuchstaben
Typvariablen beginnen immer mit Kleinbuchstaben
GHCI Befehl :t zeigt Typ eines Ausdrucks:
Prelude > :t ’a’
’a’ :: Char
e :: A gelesen als “Ausdruck e hat Typ A”
Mit dem Befehl :set +t wird der Typ jedes ausgewerteten
Ausdrucks angezeigt, mit :unset +t stellt man das wieder ab.
⇒ dauerhaft einstellbar in ghci.conf
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-19
Organisation Grundlagen Haskell GHC Typen Funktionen
Einfache Typen Zusammengesetze Typen
Wichtige Numerische Typen
Int Ganze Zahlen (“fixed precision integers”),
maschinenabhängig, mindestens von −229 bis
229 − 1. Es wird nicht auf Überläufe geprüft.
Integer Ganze Zahlen beliebiger Größe
“arbitrary precision integers”
Float Fließkommazahlen mindestens nach IEEE standard
“single-precision floating point numbers”
Double Fließkommazahlen mit mindestens doppelter
Genauigkeit nach IEEE standard
“double-precision floating point numbers”
Rational Rationale Zahlen beliebiger Genauigkeit, werden mit
dem Prozentzeichen konstruiert: 1 % 5 ≈ 0.2
’%’ nicht im Prelude-Modul enthalten
Haskell kennt viele weitere numerische Datentypen, z.B. komplexe
Zahlen, Uhrzeiten oder Festkommazahlen.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-20
Organisation Grundlagen Haskell GHC Typen Funktionen
Einfache Typen Zusammengesetze Typen
Wichtige Typen
Neben Zahlen gibt es noch weitere wichtige grundlegende Typen:
Bool Boole’sche (logische) Wahrheitswerte: True und
False
Char Unicode Zeichen, z.B. ’q’. Diese werden immer in
Apostrophen eingeschlossen.
String Zeichenketten, z.B. "Hallo!". Diese werden immmer
in Anführungszeichen eingeschlossen.
Haskell ist so knapp wie nötig formuliert. Viele Dinge, welche in
anderen Sprachen “speziell” oder “eingebaut” sind, werden in
Haskell in einer gewöhnlichen Bibliothek definiert.
Von diesen drei Typen ist lediglich Char etwas grundlegender, die
beiden anderen kann man leicht selbst definieren; doch dazu lernen
wir später noch mehr.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-21
Organisation Grundlagen Haskell GHC Typen Funktionen
Einfache Typen Zusammengesetze Typen
Kartesisches Produkt
Ein Beispiel für einen zusammengesetzten Typen hat als Vorlage
aus der Mathematik das kartesische Produkt:
Aus den Mengen A1 und A2 Mengen bildet man als kartesisches
Produkt die Menge
A1 × A2 = {(a1 , a2 ) | a1 ∈ A1 und a2 ∈ A2 }
Beispiel: (5, 8) ∈ N × N
Definition (Kartesisches Produkt)
Sind A1 , . . . An Mengen,
so ist das kartesische Produkt definiert als
A1 × · · · × An = (a1 , . . . , an ) | ai ∈ Ai für i = 1 . . . n
Die Elemente von A1 ×, . . . , ×An heißen allgemein n-Tupel,
spezieller auch Paare, Tripel, Quadrupel, Quintupel, Sextupel,. . .
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-22
Organisation Grundlagen Haskell GHC Typen Funktionen
Einfache Typen Zusammengesetze Typen
Tupel
In Haskell schreiben wir das genau so hin, lediglich im Typ
verwenden wir anstelle des Symbols × ebenfalls Klammern und
Kommas. Aus Z × Z wird also (Integer,Integer):
Prelude > :set +t
Prelude > (7 ,6)
(7 ,6)
it :: (Integer , Integer )
Prelude > (42,’a ’)
(42,’a ’)
it :: (Integer , Char)
Prelude > (True ,4.5 ,"Hi!")
(True ,4.5 ,"Hi!")
it :: (Bool , Double , String )
Prelude >
Zusammengesetzten Typen und deren Werte können wir ganz
genauso wie jeden anderen Typen verwenden.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-23
Organisation Grundlagen Haskell GHC Typen Funktionen
Einfache Typen Zusammengesetze Typen
Listen
Einer der wichtigsten Typen in Haskell sind Listen, also geordnete
Folgen von Werten. Listen schreiben wir in eckigen Klammern,
wobei die Elemente durch Kommas getrennt werden:
[1 ,2 ,3] :: [Int]
[1 ,2 ,2 ,3 ,3 ,3] :: [Int]
["Hello "," World ","!"] :: [ String ]
Im Gegensatz zu einem Tupel wissen wir anhand des Typen nicht,
wie viele Werte eine Liste enthält. Eine Liste kann sogar ganz leer
sein, geschrieben [].
Allerdings wissen wir, dass alle Elemente einer Liste den gleichen
Typ haben — diesen schreiben wir ebenfalls in eckigen Klammern
um den Listentyp hinzuschreiben; Listen sind daher homogene
Datenstrukturen.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-24
Organisation Grundlagen Haskell GHC Typen Funktionen
Einfache Typen Zusammengesetze Typen
Listen
Listen und Tupel kann man beliebig ineinander verschachteln:
[(1,’a’),(2,’z’),(-4,’w ’)] :: [( Integer , Char )]
[[1 ,2 ,3] ,[] ,[4]] :: [[ Integer ]]
(4.5 ,[( True ,’a ’ ,[5 ,7] ,())])
:: (Double , [(Bool , Char , [ Integer ], ())])
Achtung: [] und [[]] und [[],[]] und [[[]]] und [[],[[]]]
sind alles verschiedene Werte.
Das 0-Tupel ist ebenfalls erlaubt: () :: ().
Der Typ () wird als Unit-Typ bezeichnet, und hat nur den
einzigen Wert (). Aus dem Kontext wird fast immer klar, ob mit
() der Typ oder der Wert gemeint ist.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-25
Organisation Grundlagen Haskell GHC Typen Funktionen
Einfache Typen Zusammengesetze Typen
Listen
Listen und Tupel kann man beliebig ineinander verschachteln:
[(1,’a’),(2,’z’),(-4,’w ’)] :: [( Integer , Char )]
[[1 ,2 ,3] ,[] ,[4]] :: [[ Integer ]]
(4.5 ,[( True ,’a ’ ,[5 ,7] ,())])
:: (Double , [(Bool , Char , [ Integer ], ())])
Achtung: [] und [[]] und [[],[]] und [[[]]] und [[],[[]]]
sind alles verschiedene Werte.
Das 0-Tupel ist ebenfalls erlaubt: () :: ().
Der Typ () wird als Unit-Typ bezeichnet, und hat nur den
einzigen Wert (). Aus dem Kontext wird fast immer klar, ob mit
() der Typ oder der Wert gemeint ist.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-25
Organisation Grundlagen Haskell GHC Typen Funktionen
Einfache Typen Zusammengesetze Typen
Listen
Listen und Tupel kann man beliebig ineinander verschachteln:
[(1,’a’),(2,’z’),(-4,’w ’)] :: [( Integer , Char )]
[[1 ,2 ,3] ,[] ,[4]] :: [[ Integer ]]
(4.5 ,[( True ,’a ’ ,[5 ,7] ,())])
:: (Double , [(Bool , Char , [ Integer ], ())])
Achtung: [] und [[]] und [[],[]] und [[[]]] und [[],[[]]]
sind alles verschiedene Werte.
Das 0-Tupel ist ebenfalls erlaubt: () :: ().
Der Typ () wird als Unit-Typ bezeichnet, und hat nur den
einzigen Wert (). Aus dem Kontext wird fast immer klar, ob mit
() der Typ oder der Wert gemeint ist.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-25
Organisation Grundlagen Haskell GHC Typen Funktionen
Einfache Typen Zusammengesetze Typen
Typabkürzungen
Der Typ String ist nur eine Abkürzung für eine Char-Liste:
type String = [Char]
Solche Abkürzungen darf man genau so auch selbst definieren:
Hinter dem Schlüsselwort type schreibt meinen einen frischen
Namen, der mit einem Großbuchstaben beginnt und hinter dem
Gleichheitszeichen folgt ein bekannter Typ, z.B.
type MyWeirdType = (Double ,[( Bool , Integer )])
Für die Ausführung von Programmen ist dies unerheblich.
Typabkürzungen dienen primär zur Verbesserung der Lesbarkeit.
Leider ignoriert GHC/GHCi Typabkürzungen meistens, d.h. GHCi
gibt fast immer [Char] anstelle von String aus.
Es gibt noch weitere zusammengesetzte Typen, z.B. Records,
Funktionstypen, etc.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-26
Organisation Grundlagen Haskell GHC Typen Funktionen
in der Mathematik in Haskell
Funktionen
Definition (Funktion)
Für zwei Mengen A und B ist eine (totale) Funktion f von A nach
B eine Zuordnung, welche jedem Element x ∈ A genau ein
Element y ∈ B zuordnet; geschrieben f (x) = y .
Die Menge A bezeichnen wir als den Definitionsbereich von f , die
Menge B als Zielbereich.
Für eine Funktion f von A nach B schreiben wir kurz: f : A → B.
Funktionsanwendung wird auch gerne ohne Klammer in
Präfixnotation f x geschrieben, die Postfixnotation x f findet
dagegen seltener Verwendung.
Den Definitionsbereich einer Funktion f (engl. Domain) bezeichnen
wir üblicherweise mit dom(f ).
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-27
Organisation Grundlagen Haskell GHC Typen Funktionen
in der Mathematik in Haskell
Beispiel: Funktionen
Totale Funktionen
Minus : Z → Z
Nachfolgerfunktion f x
Signumfunktion


+1 falls
sgn arg = 0
falls


−1 falls
=x +1:N→N
x >0
x = 0 : R → {−1, 0, +1}
x <0
Partielle Funktionen
√
Wurzelfunktion · : R → R mit Definitionsbereich R+
Kehrwert kw x = 1/x : R → R mit Definitionsbereich R \ {0}
(
2x x > 1
foo x =
:N→N
0
x <1
mit Definitionsbereich N \ {−1, 0, +1}
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-28
Organisation Grundlagen Haskell GHC Typen Funktionen
in der Mathematik in Haskell
Partielle Funktionen
Definition (Partielle Funktion)
Eine partielle Funktion f : A → B ordnet nur einer Teilmenge
A0 ⊂ A einen Wert aus B zu, und ist ansonsten undefiniert.
In diesem Falle bezeichnen wir A als Quellbereich und A0 als
Definitionsbereich.
Ob eine Funktion partiell oder total ist, kann man nicht immer
leicht feststellen.
Wir sprechen von partiellen Funktionen, wenn bei der Berechnung
einer Funktion für ein bestimmtes Argument ein Fehler auftritt
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-29
Organisation Grundlagen Haskell GHC Typen Funktionen
in der Mathematik in Haskell
Beispiel: Funktionen
Totale Funktionen
Minus : Z → Z
Nachfolgerfunktion f x
Signumfunktion


+1 falls
sgn arg = 0
falls


−1 falls
=x +1:N→N
x >0
x = 0 : R → {−1, 0, +1}
x <0
Partielle Funktionen
√
Wurzelfunktion · : R → R mit Definitionsbereich R+
Kehrwert kw x = 1/x : R → R mit Definitionsbereich R \ {0}
(
2x x > 1
foo x =
:N→N
0
x <1
mit Definitionsbereich N \ {−1, 0, +1}
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-30
Organisation Grundlagen Haskell GHC Typen Funktionen
in der Mathematik in Haskell
Anonyme Funktionen
Merkwürdig:
√
· :: R → R Was bedeutet der Punkt?
Es ist oft praktisch, simplen Funktionen keinen besonderen Namen
zu geben, bzw. die Wurzelfunktion hat ja bereits ein eigenes
Symbol.
Aus dem Lambda-Kalkül (Alonzo Church, 1936), der
mathematischen Grundlage der funktionalen Programmierung,
nehmen wir daher die λ-Notation für anonyme Funktionen:
Nachfolgerfunktion λx . x + 1
√
Wurzelfunktion
λy . y
In Haskell schreiben wir anstelle von λ einfach einen Rückstrich \
\x -> x + 1
\y -> sqrt y
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-31
Organisation Grundlagen Haskell GHC Typen Funktionen
in der Mathematik in Haskell
Funktionen mit mehreren Argumenten
Eine Funktion, deren Quellbereich ein n-stelliges kartesisches
Produkt ist, nennt man eine Funktion der Stelligkeit n, oder auch
n-stellige Funktion
“n-ary function”,“arity”.
f :: N × N → N
f (x, y ) = x + 2y 2
Für die Anwendung zweistelliger Funktionen wird öfters die
Infixnotation verwendet: xfy
Bekannte Beispiele für zweistellige Funktionen mit gebräuchlicher
Infixnotation sind +, −, ∗, /.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-32
Organisation Grundlagen Haskell GHC Typen Funktionen
in der Mathematik in Haskell
Funktionen mit mehreren Argumenten
Eine Funktion, deren Quellbereich ein n-stelliges kartesisches
Produkt ist, nennt man eine Funktion der Stelligkeit n, oder auch
n-stellige Funktion
“n-ary function”,“arity”.
f :: N × N → N
f (x, y ) = x + 2y 2
Für die Anwendung zweistelliger Funktionen wird öfters die
Infixnotation verwendet: xfy
Bekannte Beispiele für zweistellige Funktionen mit gebräuchlicher
Infixnotation sind +, −, ∗, /.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-32
Organisation Grundlagen Haskell GHC Typen Funktionen
in der Mathematik in Haskell
Funktionen mit mehreren Argumenten
Eine Funktion, deren Quellbereich ein n-stelliges kartesisches
Produkt ist, nennt man eine Funktion der Stelligkeit n, oder auch
n-stellige Funktion
“n-ary function”,“arity”.
f :: N × N → N
f (x, y ) = x + 2y 2
Für die Anwendung zweistelliger Funktionen wird öfters die
Infixnotation verwendet: xfy
Bekannte Beispiele für zweistellige Funktionen mit gebräuchlicher
Infixnotation sind +, −, ∗, /.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-32
Organisation Grundlagen Haskell GHC Typen Funktionen
in der Mathematik in Haskell
Funktionen in Haskell
In Haskell schreiben wir Funktion ganz natürlich hin:
succ :: Int -> Int
succ x = x + 1
Wir definieren eine Funktion mit dem Namen succ, welche eine
ganze Zahl auf Ihren Nachfolger abbildet.
Den Namen des Argumentes, hier x, können wir frei wählen.
“Sprechende” Namen empfehlen sich.
Die erste Zeile, also die Angabe der Typsignatur der Funktion ist
optional, da GHC den Typ auch automatisch inferieren kann.
Man sollte immer explizite Typsignaturen hinschreiben, denn. . .
. . . Typsignaturen sind eine hilfreiche Dokumentation
. . . helfen dabei, Fehlermeldungen leserlicher zu machen
. . . können Programme manchmal effizienter machen
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-33
Organisation Grundlagen Haskell GHC Typen Funktionen
in der Mathematik in Haskell
Mehrstellige Funktionen
Mehrstellige Funktionen können wir auf zwei Arten definieren:
1-stellige Funktion mit Kartesischem Produkt
foo :: (Int ,Int) -> Int
foo (x,y) = (x + 1) * y
Hier verwenden wir ganz einfach Tupel
Echte n-stellige Funktion
bar :: Int -> (Int -> Int)
bar x y = (x + 1) * y
Hier schreiben wir einfach alle Argumente durch Leerzeichen
getrennt hintereinander.
Die zweite Variante wird oft bevorzugt; doch da eine Funktion
immer nur einen einzigen Wert zurück liefern kann, bietet es sich
manchmal an, Tupel zu verwenden.
Man kann auch leicht wechseln, Stichwort “Currying”.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-34
Organisation Grundlagen Haskell GHC Typen Funktionen
in der Mathematik in Haskell
Funktionsanwendung
Die Funktionsanwendung verwendet in Haskell primär die
Präfixnotation, d.h. man schreibt hinter dem Namen der Funktion
einfach alle Argumente, durch Leerzeichen getrennt:
Prelude >
6
succ 5
Prelude > foo (2 ,7)
21
Prelude > bar 1 8
16
Dies kann man auch mithilfe von Klammern verschachteln:
Prelude > bar (succ 5) 2
14
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-35
Organisation Grundlagen Haskell GHC Typen Funktionen
in der Mathematik in Haskell
Infixnotation in Haskell
Haskell bietet ebenfalls die Infixnotationen an, um die Lesbarkeit
des Codes zu erhöhen.
Der Programmierer gibt bei der Funktionsdefinition an, welche
Notation er bevorzugt:
infixl 6 +
(+) :: Int -> Int
(+) x
succ :: Int -> Int
succ x = x + 1
infixl oder infixr und die Zahl dahinter zeigen Haskell, in
welcher Reihenfolge mehrere Unterausdrücke ohne explizite
Klammerung zu lesen sind.
So wird zum Beispiel die Punkt-vor-Strich Regel eingehalten:
infixl 7 *
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-36
Organisation Grundlagen Haskell GHC Typen Funktionen
in der Mathematik in Haskell
Infixnotation in Haskell
Zwischen Infix- und Präfixnotation kann man jederzeit auch ad hoc
wechseln:
Mit Klammern macht man aus einer Infix-Funktion eine
gewöhnliche Präfix-Funktion:
Prelude > (+) 1 2
3
Mit Rückstrichen “backquotes” macht man aus einer
Funktion in Präfixnotation eine Infix-Funktion:
Prelude > 1 ‘bar ‘ 8
16
Man verwendet die Notation, welche die Lesbarkeit erhöht.
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-37
Organisation Grundlagen Haskell GHC Typen Funktionen
in der Mathematik in Haskell
Funktionstypen
Der Typ einer Funktion ist ein zusammengesetzter Funktionstyp,
der immer aus genau zwei Typen mit einem Pfeil dazwischen
besteht.
Klammerkonvention
Funktionstypen sind implizit rechtsgeklammert, d.h. man darf die
Klammern manchmal weglassen:
Int -> Int -> Int wird gelesen als Int -> (Int -> Int)
Entsprechend ist die Funktionsanwendung implizit linksgeklammert:
bar 1 8 wird gelesen als (bar 1) 8
Das bedeutet: (bar 1) ist eine Funktion des Typs Int -> Int!
Funktionen sind also normale Werte in einer funktionalen Sprache!
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-38
Organisation Grundlagen Haskell GHC Typen Funktionen
in der Mathematik in Haskell
Zusammenfassung
Haskell ist eine universelle Programmiersprache
“Haskell Platform” installieren, nicht nur GHC
Anzeige von Typen ggf. in ghci.conf dauerhaft aktivieren
ghc/ghci mit Option +RTS -M1g starten, um
Speicherverbrauch zu begrenzen
Haskell ist White-Space und Case sensitiv:
Einrückung beachten!
Editor sollte Tabulatoren in Leerzeichen wandeln,
oder Tabulator-weite von Editor und GHC muss
übereinstimmen
Interpreter Befehle beginnen mit Doppelpunkt, z.B. :quit
Funktionen bekommen immer nur ein Argument;
Mehrstellige Funktionen:
Entweder Produkte von Argumenten als n-Tupel oder
Ergebnis ist Funktion, welche nächstes Argument verarbeitet
Martin Hofmann, Steffen Jost
Programmierung und Modellierung
01-39
Herunterladen