From: 2weiEmu Date: Tue, 11 Feb 2025 11:26:54 +0000 (+0100) Subject: fp lecture 2 X-Git-Url: https://git.saalbach.dev/?a=commitdiff_plain;h=7a78fe0c3e2699e550362366a0ca0b2bdcc8d63a;p=research-obsidian.git fp lecture 2 --- diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 01b5468..ea894d3 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -13,7 +13,7 @@ "state": { "type": "markdown", "state": { - "file": "Functional Programming/Functional Programming Introduction.md", + "file": "Functional Programming/Lecture 2.md", "mode": "source", "source": false, "backlinks": true, @@ -28,7 +28,7 @@ } }, "icon": "lucide-file", - "title": "Functional Programming Introduction" + "title": "Lecture 2" } } ] @@ -88,7 +88,8 @@ } ], "direction": "horizontal", - "width": 300 + "width": 300, + "collapsed": true }, "right": { "id": "52c8cd2985704b8e", @@ -175,6 +176,8 @@ }, "active": "d417039fb31acf08", "lastOpenFiles": [ + "Functional Programming/Functional Programming Introduction.md", + "Functional Programming/Lecture 2.md", "Ruxi.md", "Pasted image 20250207160807.png", "Documents Archive Organisational Notes.md", @@ -210,7 +213,6 @@ "Recontextualising Creativity/RC Reading Responses/Reading Response Week 6", "PoC/PoC Teamwork/PoC Coaching 5-12-2024.md", "PoC/PoC Research (Poster)/PoC Poster Overview.md", - "PoC/PoC Research (Poster)/PoC Poster References.md", - "Freedom by Angela Merkel/Notes on Freedom by Angela Merkel.md" + "PoC/PoC Research (Poster)/PoC Poster References.md" ] } \ No newline at end of file diff --git a/Functional Programming/Lecture 2.md b/Functional Programming/Lecture 2.md new file mode 100644 index 0000000..cc38144 --- /dev/null +++ b/Functional Programming/Lecture 2.md @@ -0,0 +1,154 @@ +The list of values from i to j is written: +[i..j] + +- [1..10] = [1,2,3,4,5,6,7,8,9,10] +- [1,3..10] = [1,3,5,7,9] +- [42..42] = [42] +- [10..1] = [] +- [10,8..1] = [10,8,6,4,2] + +# List Comprehensions +`[ x * x | x <- [1..5] ] = [1,4,9,16,25]` +x <- [1..5] is the generator +You can have multiple generators. + +the order of the generator matters -> it won't change the result but the order of the result. The outer loop will be the first list, the inner one the second list etc. etc. + +Later generators can depend on previous ones. +`[10 * x + y | x <- [1..3], y <- [x..3] ]` + +We can select only elements that satisfy a boolean predicate. +`[x | x <- [1..10] , even x ]` even is called a 'guard'. A guard must return type 'Bool'. + +```haskell +addMod3Is2 :: [Int] -> [Int] +addMod3Is2 x = [a + 3 | a <- x , x `mod` 3 === 2] + +-- the `` simply mean that you want to use infix notation + +concat :: [[Int]] -> [Int] +concat xss = [y | x <- xss, y <- x] +``` + +# Defining and Testing Functions +## Pattern Matching +We can define functions by case analysis using pattern matching: + +```haskell +not :: Bool -> Bool +not True = False +not False = True +``` + +One of the most powerful ones, will have to use it a lot. + +A pattern var matches any value that didn't match the prev patterns: + +```haskell + +rank 1 = "first" +rank 2 = "second" +rank 3 = "third" +rank n = show n ++ "th" +``` + +A wildcard `_` is like a pattern value for which you don't care about the value. + +can even be used for curried functions, wonderful +```haskell +xor :: Bool -> Bool -> Bool +xor True False = True +xor False True = True +xor _ _ = False +``` + +The order does matter. Haskell will use the first clause that matches. + +infix operations such as (+), (-), (!!) are just regular haskell functions +- name must consist of special chars only +must be parentesized when appearing by themselves +Can be used as normal: +`(+) 1 1 == 1 + 1` + +lists in haskell are singly linked list + +```haskell +isEmpty :: [a] -> Bool +isEmpty [] = True +isEmpty (x:xs) = False +``` +Any list is either [] or x:xs +`[1,2,3]` is sugar for `1:2:3:[]`, this is important so that technically 'single' item lists, are actually two element lists and therefore match (x:xs) anyway. + +## Using Guards +we can use guards to add boolean conditions to a clause + +```haskell +signum x + | x < 0 = -1 + | x == 0 = 0 + | otherwise = 1 +``` + +Guards `| b` appear after the patterns (and before =) +The condition be should be type bool +otherwise is defined to be always True + +mixing guards and pattern matching + +```haskell +capitalize :: String -> String +capitalize (c : cs) + | isLower c = (toUpper c) : cs +capitalize cs = cs +``` + +will continue until it finds one that matches + +## Recursion + +there is the 'error' function. another reason why haskell is partial. +cannot call a function inside a pattern, typically you have to do guards. + +a 4 step plan for implementing a (recursive) function\ +- write down the type +- enumerate the cases +- define the base cases +- define the recursive cases + +## Polymorphic Types + +we don't want multiple function definitions for different types, for length we want more than just [Int] for example +so not +`length :: [Int] -> Int`, but something more general +sure sometimes we also want to restrict it a bit. + +length function is easy, for example: +`length :: [a] -> Int`, we don't have to define it, since haskell can infer + +## Type Classes +What should be the type of double x = x + x +Int -> Int , does not include floats etc. +but a -> a doesn't work, doesn't work for bools for example +Solution, Add a constraint: +```haskell +-- Num a => + +double :: Num a => a -> a +-- I assume you can find these groups in the standard lib. + +-- the num thing +-- num ia an example of a type class, a collection of types that support a common interface +class Num a where + (+) :: a -> a -> a + (-) :: a -> a -> a + (*) :: a -> a -> a + negate :: a -> a + abs :: a -> a + fromInteger :: Integer -> a +``` + +you cannot use the 'num' type on its own, its a constraint not a type itself, so you can't have `[Num]` + +There is the `Eq` class. +`Ord` class, things that can be ordered. Subclass of `Eq`