Programowanie funkcyjne jest stylem programowania opartym na obliczaniu wartości wyrażeń, w przeciwieństwie do programowania imperatywnego, wykorzystującego modyfikacje stanu programu przez instrukcje. Studenci znają już ten paradygmat z przedmiotu "Metody programowania", gdzie były wykorzystywane języki Racket i Plait. Celem tego wykładu jest pogłębiona prezentacja programowania funkcyjnego w świecie języków z bogatymi systemami typów. W trakcie wykładu będą przedstawione pojęcia i techniki programowania funkcyjnego z wykorzystaniem dwóch dojrzałych języków programowania (OCaml i Haskell) oraz kilku eksperymentalnych (Helium, Idris, ...). Spora część wykładu będzie dotyczyła programowania z rozmaitymi efektami obliczeniowymi (stan, wejście/wyjście, nawroty, kontynuacje) w czysto funkcyjny sposób.
### Wymagania
* Metody programowania
### Program
1. Algebraiczne typy danych i dopasowanie wzorca
2. Abstrakcja danych i system modułów
3. Wybrane trwałe struktury danych
4. Modyfikowalny stan i leniwość
5. Uogólnione algebraiczne typy danych (GADT)
6. Styl kontynuacyjny (CPS)
7. Monady
8. Klasy typów
9. Transformatory monad
10. Indeksowane rodziny typów
11. Efekty algebraiczne
12. Elementy programowania z typami zależnymi