diff --git a/makefile b/makefile new file mode 100644 index 0000000000000000000000000000000000000000..65a2828ca2850b840a34f923a1cf9639bd9e41db --- /dev/null +++ b/makefile @@ -0,0 +1,14 @@ +inputs = $(shell ls src/*.md) # $(wildcard src/*.md) outputs in the wrong order +pandoc = pandoc $(inputs) -f markdown -t beamer \ +--slide-level 2 -V theme:metropolis -H theme.tex + +slides.pdf: $(inputs) res/* theme.tex + $(pandoc) --pdf-engine=xelatex -o $@ + +slides.tex: $(inputs) theme.tex + $(pandoc) -o $@ + +clean: + rm -f slides.pdf slides.tex + +.PHONY: clean diff --git a/res/certificate.png b/res/certificate.png new file mode 100644 index 0000000000000000000000000000000000000000..e22e89792b8cf69d8454fe82ab228afa78389196 Binary files /dev/null and b/res/certificate.png differ diff --git a/res/logo-haskell.png b/res/logo-haskell.png new file mode 100644 index 0000000000000000000000000000000000000000..a6757cb2fa9b8bd1e6150bae2448d999e5eee9ad Binary files /dev/null and b/res/logo-haskell.png differ diff --git a/slides.pdf b/slides.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f92fdbb634737a80a21496693e456b5f112da712 Binary files /dev/null and b/slides.pdf differ diff --git a/src/00-introduction.md b/src/00-introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..4550cc3d558961ec741228c39a09655078dac1c2 --- /dev/null +++ b/src/00-introduction.md @@ -0,0 +1,71 @@ +--- +title: Functional Programming +subtitle: An introductory Workshop +author: Nicolas Lenz +institute: "[eisfunke.com](https://www.eisfunke.com)" +titlegraphic: res/logo-haskell.png +--- + +# Introduction + +## Me + +**Hello!** + +Nicolas Lenz + +- Master student, first semester +- Fachschaftsrat +- FOSS-AG +- Functional programming/theoretical computer science fan + +## Contact & Links + +**Mail:** \ +[nicolas.lenz@udo.edu](mailto:nicolas.lenz@udo.edu) + +**Homepage** (with more contact data and links to projects): \ +[eisfunke.com](https://www.eisfunke.com) + +**My GitLab instance** (with some Haskell stuff): \ +[git.eisfunke.com](https://git.eisfunke.com) + +You can find the source code of these slides at <https://git.eisfunke.com/education/fupro>. + +## Interaction & Questions + +Interaction is important. Don't hesitate to ask questions! + +Questions not relevant to everybody will be answered in group phase. + +## Material + +Very good, fun to read, free to read online and base for this workshop: + +*Learn You a Haskell for Great Good!* by Miran Lipovača (<http://learnyouahaskell.com/>) + +## Certificate + +\centering + + + +## Haskell + +We'll be using [Haskell](https://www.haskell.org/). + + + +- Since 1990 +- Purely functional +- Statically & strongly typed +- Used in academic context + +## Other Functional Languages + +- Scala +- Lisp +- Scheme +- F# +- [Lightfold](https://git.eisfunke.com/software/lightfold/lightfold) +- Many others in varying degrees diff --git a/src/01-basic-usage.md b/src/01-basic-usage.md new file mode 100644 index 0000000000000000000000000000000000000000..fa56c3c7146946089f279f333151d10154a0de99 --- /dev/null +++ b/src/01-basic-usage.md @@ -0,0 +1,39 @@ +# Basic Usage + +## Installation + +- Recommended: Install the [Haskell Platform](https://www.haskell.org/platform/) +- Includes everything you need to start with Haskell +- Just installing the GHC alone is enough for this workshop + +## GHCI + +*"Glasgow Haskell Compiler"* is the Haskell compiler everyone uses. + +*GHCi* (i = interactive) is an interactive "language shell" for Haskell (command: `ghci`). + +- Enter a Haskell expression to see the result +- Can use definitions from a Haskell program in a file +- Various commands beginning with `:`: + - `:load` / `:l file.hs`: Load the content of a file. + - `:reload` / `:r`: Reload loaded files (use when files changed) + - `:info` / `:i`: Get information on a function, type, … + - `:type` / `:t`: Get the type of an expression + - `:quit` / `:q`: Close GHCi + - `:help` / `:h`/`:?`: Get a list of available commands + +**Make sure you can open a file in GHCI!** + +## Compiling + +Haskell can of course also be compiled into executable programs with `ghc`, but that comes later. + +For now we'll use only the GHCi. It's great for trying out stuff. + +## Stack + +Just so you know: for projects, you'd want to use Stack. + +https://docs.haskellstack.org/en/stable/README/ + +All-in-one build tool & "package manager" diff --git a/src/02-what-is-functional-programming.md b/src/02-what-is-functional-programming.md new file mode 100644 index 0000000000000000000000000000000000000000..4d8372267cb5fd49b1c79cf124095e70c4cca66b --- /dev/null +++ b/src/02-what-is-functional-programming.md @@ -0,0 +1,28 @@ +# What is Functional Programming? + +## The Difference + +- *Imperative* vs. *Functional* +- Programming lanuages like Java or C are imperative +- Imperative: program is list of commands to be executed one after another + +``` +x = 3 +do_thing(x) +x = x + 4 +y = 2 +do_another_thing(x, y) +``` + +## Functional + +- Different approach +- In functional programming a program is no list of commands +- More a *collection of definitions* + +``` +x = 4 +x = 2 +``` + +What will happen? diff --git a/src/03-first-functions.md b/src/03-first-functions.md new file mode 100644 index 0000000000000000000000000000000000000000..fed7e9fcdc131397077d52fd02e77dd4ef07632a --- /dev/null +++ b/src/03-first-functions.md @@ -0,0 +1,45 @@ +# First Functions + +## Basic Calculation + +`x = 1` defines `x` to hold the value `1` as already seen. + +Basic calculations work as expected + +- `1 * 2` +- `2 / 2` +- `3 + 1` +- `1 - 3` + +`3 + 1 * 20` vs. `(3 + 1) * 20` + +## Truth values + +Truth values: `True` and `False` (*capitalized!*) + +- `True && False` +- `True || False` +- `not False` + +## Comparisons + +Comparisons also work as expected. + +- `5 == 5` +- `3 > 2` +- `1 >= 10` +- `2 /= 2` (note that not `!=`) + +## First Functions + +```haskell +double x = x * 2 + +six = double 3 + +isThree x = x == 3 + +isOneMore x y = x - 1 == y + +result = isOneMore 3 6 +``` diff --git a/src/04-first-types.md b/src/04-first-types.md new file mode 100644 index 0000000000000000000000000000000000000000..3f8f5159c7fe1a0e9b7f758cf3a003e09e0d5e96 --- /dev/null +++ b/src/04-first-types.md @@ -0,0 +1,64 @@ +# First Types + +## What is a Type? + +- "Classifies" values +- Constrains what a value can be + +## Basic Types in Haskell + +- `Int`: Integer numbers (`-1`, `0`, `30`) +- `Boolean`: Truth values (`True`, `False`) (*capitalized!*) +- `Char`: Single characters (`'a'`, `'c'`) +- `String`: Text (`"Hello"`, `"Cheese sandwich"`) +- `a -> b`: Function with the + +## Specifying a Type + +```haskell +x :: Int +x = 5 + +favoriteAnimal :: String +favoriteAnimal = "Cat, obviously" + +firstLetter :: Char +firstLetter = 'A' + +double :: Int -> Int +double x = x * 2 +``` + +Recommendation: Always specify the type. + +## Lists + +Ordered list with elements of type `a`: `[a]` + +```haskell +fruits :: [String] +fruits = ["Banana", "Apple", "Raspberry"] + +numbers :: [Int] +numbers = [1,5,2] + +empty :: [Int] +empty = [] +``` + +## Building Lists + +Lists are a *recursive data structure* + +A list is always either +- *an empty list* or +- *an element added in front of another list*. + +Adding an element is done with `:` + +`[1,2,3]` is the same as `1 : (2 : (3 : []))` + +```haskell +moreFruits :: [String] +moreFruits = "Orange" : fruits +``` diff --git a/src/05-first-logic.md b/src/05-first-logic.md new file mode 100644 index 0000000000000000000000000000000000000000..338f51d2b7c0f639fa0a879569f5bea5ef8847d5 --- /dev/null +++ b/src/05-first-logic.md @@ -0,0 +1,42 @@ +# First Logic + +## Decisions + +`if .. then .. else ..` is possible + +Must always have `else` (otherwise result could be undefined, not functional)! + +```haskell +rate :: Int -> String +rate x = if x > 42 then "big" else "small" +``` + +## Pattern Matching + +You can use multiple definitions for different patterns of the input + +```haskell +double :: Int -> String +double 1 = "zwei" +double 2 = "vier" +double x = "calculate it yourself" +``` + +Pattern matching can "disassemble" values + +```haskell +tail :: [Int] -> [Int] +tail [] = [] +tail (x:xs) = xs +``` + + +## Recursion + +Recursion is main method of repetition (loops are not very functional) + +```haskell +doubleAll :: [Int] -> [Int] +doubleAll [] = [] +doubleAll (x:xs) = (x * 2) : xs +``` diff --git a/src/06-finding-documentation.md b/src/06-finding-documentation.md new file mode 100644 index 0000000000000000000000000000000000000000..43bd511c6101c7392cbb00078697d614cacaf912 --- /dev/null +++ b/src/06-finding-documentation.md @@ -0,0 +1,5 @@ +# Finding Documentation + +## Hoogle + +https://hoogle.haskell.org/ diff --git a/src/07-simple-io.md b/src/07-simple-io.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/08-higher-order.md b/src/08-higher-order.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/theme.tex b/theme.tex new file mode 100644 index 0000000000000000000000000000000000000000..100b722b7a6267ed1422ca1d54b537a4a67ff1ce --- /dev/null +++ b/theme.tex @@ -0,0 +1,52 @@ +\definecolor{primary-medium}{HTML}{F19204} +\definecolor{accent-bright}{HTML}{F07D8F} +\definecolor{accent-light}{HTML}{EB4F67} +\definecolor{accent-medium}{HTML}{E41131} +\definecolor{accent-dim}{HTML}{A90D24} +\definecolor{background-very-dark}{HTML}{232124} +\definecolor{background-dark}{HTML}{3F3C41} +\definecolor{background-super-bright}{HTML}{F8F7F8} + +\metroset{sectionpage=progressbar, progressbar=frametitle, titleformat=smallcaps, background=light} + +\setbeamercolor{normal text}{fg=black} +\setbeamercolor{background canvas}{fg=background-dark, bg=background-super-bright} +\setbeamercolor*{palette primary}{fg=white,bg=primary-medium} +\setbeamercolor*{progress bar}{fg=accent-dim, bg=accent-bright} + +\setlength{\leftmargini}{1em} + +\usepackage{sourcesanspro} +\usepackage{sourcecodepro} + +\usepackage{polyglossia} + \setdefaultlanguage[variant=american]{english} +\usepackage{listings} + + + +\usepackage{mathtools, amssymb, stmaryrd, unicode-math} +\usepackage{xspace} + +\usepackage{fvextra} +\usepackage{color} +\usepackage{fancyvrb} +% \renewcommand{\VERB}{\Verb[commandchars=\\\{\}]} +\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\},breaklines,fontsize=\small} +\DefineVerbatimEnvironment{verbatim}{Verbatim}{commandchars=\\\{\},breaklines,fontsize=\small} + +% \input{macros.tex} + +\lstnewenvironment{algorithm}{ + \lstset{ + mathescape=true, + escapeinside={(*}{*)}, + keepspaces=true, + numbers=left, + numberstyle=\tiny, + columns=fullflexible, + keywordstyle=\bfseries, + keywords={repeat, until, for, all, each, in, return, function, if, else, or, and, empty}, + numbers=left + } +}{} diff --git a/work/2021-01-15.hs b/work/2021-01-15.hs new file mode 100644 index 0000000000000000000000000000000000000000..6c9e17dafb095b112a42a87b8a512938719e4ecc --- /dev/null +++ b/work/2021-01-15.hs @@ -0,0 +1,30 @@ +kaese :: Int +kaese = 1 + +brot :: Int +brot = 3 + +double :: Int -> Int +double x = x * 2 + +addKaese :: Int -> Int +addKaese x = x + kaese + +isEqual :: Int -> Int -> Bool +isEqual x y = x == y + +fruits :: [String] +fruits = ["Apple", "Banana"] + +doubleName :: Int -> String +doubleName 1 = "Zwei" +doubleName 2 = "Vier" +doubleName x = "Mir egal" + +withoutFirst :: [Int] -> [Int] +withoutFirst (x : xs) = xs +withoutFirst [] = [] + +doubleAll :: [Int] -> [Int] +doubleAll [] = [] +doubleAll (x : xs) = x * 2 : doubleAll xs