Fortgeschrittene funktionale Programmierung in Haskell

FFPiH ist eine Vorlesung, die ich zusammen mit einem Kommilitonen im Sommer 2015 erstmals erstellt und gehalten haben.

Insgesamt haben wir die Vorlesung 3x gehalten, wobei von der ersten zur zweiten Iteration der Inhalt massiv überarbeitet wurde und bei der Iteration von der zweiten zur dritten Vorlesung die Übungen komplett neu erstellt wurden.

Die gesamten Übungen sind unter anderem in der FFPiH-Organisation in meinem gitea hinterlegt: https://gitea.dresselhaus.cloud/FFPiH

Einige der aktualisierten Übungen sind privat geschaltet, da diese iterativ aufeinander aufbauen und jeweils die Musterlösung der vorherigen enthalten.

Aufbau der Vorlesung

Vorausgesetzt wurde, dass die Studierenden das erste Semester abgeschlossen hatten und somit bereits leichte Grundlagen in Haskell kannten (aber z.b. Dinge wie Functor/Applicative/Monad noch nicht wirklich erklärt bekommen haben).

Stück für Stück werden die Studis dann zunächst in abstrakte Konstrukte eingeführt, aber diese werden dann schnell in die Praxis umgesetzt. Etwa mit dem Schreiben eines eigenen Parsers.

Schlussendlich gibt es dann einen “Rundumschlag” durch die gesamte Informatik. Erstellung eines Spieles (auf basis einer kleinen Grundlage), erstellung von WebApps mit Yesod, Parallelisierung und Nebenläufigkeit für rechenintensive Anwendungen inkl. synchronisation mittels STM.

Optional gab es weitere Übungen zu dingen wie “verteiltes Rechnen”.

Ziel hierbei war nicht, diese ganzen Themen in der Tiefe beizubringen, sondern aufzuzeigen, wie sie sehr schnell abstrakte Konstrukte, die ihnen ggf. 3 Semester später erst begegnen bugfrei benutzen können, da Haskell hier in sehr vielen Fällen einfach nur die “richtige” Lösung kompilieren lässt und alle gängigen Fallen schlicht ausschließt. Beispiel ist z.b. STM innerhalb von STM, Mischen von DB-Monade, Handler-Monade und Template-Engine in Yesod, Process () statt IO () in der Nutzung von CloudHaskell, etc. pp.

Studentisches Feedback

Sehr gutes Feedback von den Studenten bekamen wir insbesondere für Übungen wie:

Übung 2, Aufgabe 2, weil hier durch “einfaches” umformen hin zu Abstraktionen und mit den Regeln dieser im ersten Fall die Laufzeit (vor Compileroptimierungen) von O(n²) auf O(0) ändert.

Übung 4, welche ein komplett fertigen (sehr rudimentären und simplen) Dungeon-Crawler bereitstellt, der “nur” 1-2 bugs hat und “wie ein echtes Projekt” erweitert werden muss. Diese Übung hat sich dann über 4 weitere Übungen gestreckt, wobei folgende Aufgaben gelöst werden müssen:

  • Einarbeitung in QuickCheck zur Behebung eines Bugs im Test
  • Umschreiben von explizitem Argument-Passing hin zu Monad-Transformers mit stateful lenses
  • Continuation-Basierendes Event-System
  • Hinzufügen eines Parsers für Level, Items & deren Effekte und implementation dieser
  • Ändern des GUI-Parts von CLI auf 2D GL mittels gloss
  • Ändern von StateT World auf RWST GameConfig Log World und somit nutzen von individuellen Konfigurationen für z.b. Keybindings