the difficulty of each exercise went from 0 to 100 real quick..
@Jojkata9
4 жыл бұрын
Give this man a medal of honor
@drvanon
3 жыл бұрын
Was thinking something like that. The quality of education here is just through the roof.
@ragnadrok7
3 жыл бұрын
Ex1: cute, that was easy Ex3: This is above my pay grade.
@VladTrishch
4 жыл бұрын
Please, don't stop making these
@burnytech
2 жыл бұрын
Amazing excercises! I loved the last one, i accidently implemented other way around in the tree instead like this: foldtrieright :: (b -> a -> b) -> b -> Trie a -> b foldtrieright op acc (Node x ht) = op (foldr (flip (foldtrieright op)) acc ht) x foldtrieright op acc (Leaf x) = op acc x
@santiagolerin
4 жыл бұрын
It took me an absurdly long time to finish the last one because I wasn't able to use the values of the tree, until I figured I needed to wrap the constructor between parenthesis. My solution was: foldtrie f acc (Leaf x) = f acc x foldtrie f acc (Node x xs) = foldl (foldtrie f) (f acc x) xs
@suvrat
3 жыл бұрын
Thank you so much for these lectures Philipp! You are awesome! :)
@theantonlulz
4 ай бұрын
Exercise 2 is the prefect argument against functional programming.
@TheTIM333
3 ай бұрын
prefixes = [take m n | m
@shipweck6253
2 ай бұрын
@@TheTIM333 came up with that but then when i unpaused he said to specifically use folding and then i sat there and tried only for the actual solution in the video to be horribly unreadable and unconcise
@TheTIM333
2 ай бұрын
@@shipweck6253 I agree, it is not exactly the most elegant but this cannot be used as an argument against functional programming as using folding was arbitrarily imposed for the purpose of the exercise.
@kellybmackenzie
Жыл бұрын
Thank you so much, these exercises were amazing!!
@inserteunnombreapropiado9079
23 минут бұрын
Too late to comment, but I would have suggested to add a visual representation of the solutions as it's difficult to visualize them in my head. My take on 2nd: prefixes = rev . foldl (\acc x -> if null acc then acc ++ [[x]] else (head acc ++ [x]) : acc) [] My take on 3rd: lagrange :: [(Float, Float)] -> Float -> Float lagrange p x = foldl (\acc (xj, yj) -> acc + (yj * smolL xj)) 0 p where smolL :: Float -> Float smolL xj = foldl (\acc (xm, _) -> acc * (if xm == xj then 1 else (x - xm) / (xj - xm))) 1 p
@Russoski234
Жыл бұрын
I feel exercise 3 and 4 is more geared toward understanding and applying declarative programming than resolving it, testing it and debugging it with ghci and some input. I got a bit confused, is the next paragraph the correct reasoning for what's happening in exercise 4? Function f is never really defined but only declared in the foldtrie signature, where 'f acc x' returns a 'b'. Moving on, in the case of a Leaf, foldtrie returns a 'b'; if it's a node with a sub-tree, we fold it starting with a 'b' (that we get by calling 'f acc x') and we give the rest of the sub-tree (xs) to the folding, according per what f' is, i.e. a recursive call to foldtrie. So we navigate the tree according to the order of the list, while the accumulator 'b' gets constantly updated. In the end, the function returns a 'b', that is the last leaf visited.
@frankmartinez2987
3 жыл бұрын
I was completely lost on that last exercise. Can you walk us thru it in more detail, please? Thanks in advance.
@julien8097
11 ай бұрын
exercice 4 is too confusing, tbh i don't even know the problem wasn't presented well enough or if i'm an idiot .. haskell is confusing af anyways thanks for these videos man !
@Daniel-ws9qu
4 жыл бұрын
Bester Tutor
@alexanderskusnov5119
4 жыл бұрын
Yeah, before him I knew only one - Tsoding
@suvrat
3 жыл бұрын
I was trying all the exercises with both foldl and foldr. For the `prefixes` exercise, is this the right way to do it with `foldl`: prefixes_foldl :: [a] -> [[a]] prefixes_foldl = foldl (\acc e -> if (length acc) == 0 then [e] : acc else acc ++ [(last acc) ++ [e]]) [] Or is there a better way? Is this too imperative?
@toomanycharacter
Жыл бұрын
Well, you should replace "if (length acc) == 0)" with "if null acc". Also, replace "then [e] : acc" with "then [[e]]". Otherwise, I think it's quite a good solution
@carlorosso2413
3 ай бұрын
In the third exercise I understood why you say that Haskell is pure: lagrange :: [(Float, Float)] -> Float -> Float lagrange xs x = sum [y_i * lagrangeBasis xs x_i x | (x_i, y_i)
@lukekim825
2 жыл бұрын
Great tutorial!
@myxail0
Жыл бұрын
For the third example I came up with the following: lagrange l x = sum $ zipWith (\i y -> basis' i x * y) [0..] ys where basis' = basis xs (xs, ys) = unzip l basis :: [Float] -> Int -> Float -> Float basis xs i x = prod' x / prod' xi where prod' = flip prod xs' prod e = product . map ((-) e) xs' = a ++ b (a, xi:b) = splitAt i xs
I might be mistaken, but shouldn't the l function in exercise #3 @ 8m3s check the *index* m == j, and not that the *value* of xm == xj? In my solution I had to first use `zip [0..] xs` to get that index.
@philipphagenlocher
4 жыл бұрын
You are not mistaken! The formal definition requires us to check the index and not the value. However, a list of data points will contain any x value *only once* since otherwise it would specify that a value x has more than one value (which makes no sense for interpolation). Since we only need to check if the indices are the same we can do that by comparing the values. If the values are the same the indices have to be the same and if the values are different the indices have to be different.
@lizzienovigot
3 жыл бұрын
Doesn't matter in practice, because if some x's are the same, you will be dividing by zero ar some point. In real life these type of calculations are always done in cases when x's are all different.
@Merlin-gl7zp
Ай бұрын
3:00 My solution, i was struggling with `rev` ```Haskell unwrap :: [[a]] -> [a] unwrap [] = [] unwrap [] (x:xs) = x prefixes list = rev (foldl (\acc x -> (rev (x : (rev(unwrap acc)))) : acc ) [] list) ```
@NamasteProgramming
Жыл бұрын
Me: Here for Haskell tutorial Math: 😎😎😎 ☠️☠️☠️
@macicoinc9363
2 жыл бұрын
Lol, you don't know how happy I was when my solution to 3 just worked: lagrange k xp = foldr (\(x,y) acc -> acc + y * foldr(\(x1,_) acc1 -> if x/=x1 then acc1 * (xp-x1)/(x-x1) else acc1) 1 k) 0 k
@ayushchaudhari5655
2 жыл бұрын
The solution to exercise #2 was not clear to me, so I came up with an extremely hacky solution: prefixes = (\(x:xs) -> xs) . foldl (\acc x -> acc ++ [(last acc) ++ [x]]) [[]] Could you explain why and how you used foldr in prefixxes instead of foldl more clearly? Edit: Sorry, figured it out😅: pre = foldr (\x acc -> [x] : [x:xs | xs
@ragilo13
8 ай бұрын
Ex3 + 2 hours and i finally made it work. But i guess not the best way how i did it: lagrange'' :: [(Float, Float)] -> (Float -> Float) lagrange'' xs = (\k -> foldr (\(xi, yi) acc -> acc + yi * foldl (\acc (x, _) -> acc * ((k - x) / (xi - x))) 1 (filter (\(x, _) -> x /= xi) xs)) 0 xs)
@eloidrai3608
3 жыл бұрын
EXERCICE 1 : rev = foldl (\acc e -> e:acc) []
@rogierverkaik1
2 жыл бұрын
I solved exercise 2 with scanl. I find that a bit more intuitive and readable. What do you think? prefixes = tail . scanl (\acc x -> acc++[x]) []
@micknamens8659
2 жыл бұрын
Yes, the structure of the output somehow suggests to use scanl. Although the "++" operation needs n (:) operations when appending to a list of n elements, it only needs to be applied once per item whereas the (:) has to be applied for all elements in the result list which grows from 1 to n. So the internal evaluation might be the same as with foldr.
@dionysusheir4112
3 жыл бұрын
I run into: error: parse error on input `->', despite copying the solutions verbatim.
@EthanBradley1231
2 жыл бұрын
You could Eta reduce to eliminate the where statement in the foldtrie function. Just replace f' in the body of the function with "foldtrie f," then you don't need to reference f', so you don't need to make f'
@user-tk2jy8xr8b
2 жыл бұрын
You need more smiles in the 2nd excersise: foldr (\x -> map (x :) . ([] :)) [] [1,2,3]
@mumk
Жыл бұрын
very difficult... Im bad
@colin398
Жыл бұрын
This language is beautiful but so hard to wrap my head around after learning C++
@WilcoVerhoef
4 жыл бұрын
7:34 "we cannot use prod" You could use prod and divide out the term you don't want in there, right?
@runamilkay
3 жыл бұрын
The “reason” we’re excluding that term is because it’s undefined due to a division by zero, so we can neither take the full product nor divide by it! But yeah, if it were defined, your suggestion would be slick! (though now that I think about it, I don’t know how division really works - is it better for float accuracy to try to stick with multiplication when you can?)
@WilcoVerhoef
3 жыл бұрын
@@runamilkay ah good point, I can't find another way around it then
@WilcoVerhoef
3 жыл бұрын
@@runamilkay Multiplication and division are both equally accurate, and you cannot substitute one for the other anyway (without taking more steps). The prod that I proposed just added a few extra steps (one more multiplication and division), so it would've been a little less accurate. I googled a bit and found this article: docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html Turns out it's subtraction of very similar big values that causes big errors, but you can sometimes reorder and change some operators to make the subtraction happen on smaller numbers. good x y = (x+y)*(x-y) bad x y = x^2 - y^2 I tried 99999999 99999995. Answer should be 8e9; as both functions correctly exacty calculate. But by defining the values to be ::Floats, the 'good' result was 16e9 and the bad even 21e9 :o
@manaswidaksha137
3 жыл бұрын
Why do you keep using foldl instead of foldr? Is there a performance benefit or something?
@philipphagenlocher
3 жыл бұрын
Mostly preference. Some languages that have a similar folding function (Python has "reduce" for example) mostly use a left folding instead of right folding, which is why I tend to use foldl in this video. In personal projects however I'd rather go with foldr due to it's strict variant foldr' which can be used as a drop-in replacement for performance tuning.
@myxail0
Жыл бұрын
foldl is really lazy and can be used on infinite lists, so that's kinda neat
ex 1: easy ex 2: made me think a bit, but still easy ex 3: no idea what the problem is. my maths is not so good. if you need strong maths to get on in Haskell than I'd better stop here :-(
Пікірлер: 58