-
-
Notifications
You must be signed in to change notification settings - Fork 848
Completed Chapter 1, 2, 3 and 4 #583
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
vrom911
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked through the Chapter 1! Great work so far, left some comments too 🙏🏼
| 49 | ||
| -} | ||
|
|
||
| squareSum :: Num a => a -> a -> a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We explain Num in the following chapters, so you are one step ahead 😸
In here Int -> Int -> Int would also work, as a more specific type 🙂
| -- DON'T FORGET TO SPECIFY THE TYPE IN HERE | ||
| lastDigit n = error "lastDigit: Not implemented!" | ||
| lastDigit :: Integral a => a -> a | ||
| lastDigit n = n `mod` 10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your implementation is almost correct 🆗
Unfortunately, it returns negative numbers on negative inputs because of how mod works. Sometimes corner cases can be tricky to spot and fix...
| -- mid x y z | ||
| -- | x > y = mid y x z | ||
| -- | y > z = mid x z y | ||
| -- | otherwise = y |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really smashed it! Nice ideas all around 💡
| -} | ||
| isVowel c = error "isVowel: not implemented!" | ||
| isVowel :: Char -> Bool | ||
| isVowel c = c `elem` "aeiouy" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice one! 👍🏼
One note in here, that sometimes, elem could be slower than the explicit pattern matching. I remember there were some benchmarks on one particular case, that showed how moving to pattern matching on each case separately drastically decrease time 🐎
| sumLast2 :: Integral a => a -> a | ||
| sumLast2 n = | ||
| let lastDigit = n `mod` 10 | ||
| secondLastDigit = (n `div` 10) `mod` 10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a wonderful solution! 👏🏼 You correctly noticed that it is the div and mod, cool 😎
One hint to make your solution even shorter: you can see that you use both:
mod m 10
div m 10The standard library has the divMod function, that actually combines inside both div and mod. And this is exactly what you use!.
So you could write it this way:
(x, y) = divMod m 10You can see how we could pattern match on the pair 🙂
| firstDigit :: Integral t => t -> t | ||
| firstDigit n | ||
| | n < 10 = n | ||
| | otherwise = firstDigit (n `div` 10) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that for a negative number like -19, this implementation will return the negative number itself instead of the first digit because the first check n < 10 will always succeed for negative numbers.
vrom911
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wonderful work on Chapter 2! Only a few notes 🥇
| duplicate l = reverse (go [] l) | ||
| where | ||
| go :: [a] -> [a] -> [a] | ||
| go acc [] = acc | ||
| go acc (x:xs) = go (x : x : acc) xs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a nice solution, however, reverse is quite costly!
And also it is not needed here, cause the list you create in the go function is already exactly what we need!
|
|
||
| takeEven :: [a] -> [a] | ||
| takeEven [] = [] | ||
| takeEven (x:[]) = [x] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haskell syntax allows to simplify this:
| takeEven (x:[]) = [x] | |
| takeEven [x] = [x] |
| -- Can you eta-reduce this one??? | ||
| pairMul xs ys = zipWith (*) xs ys | ||
| pairMul :: [Integer] -> [Integer] -> [Integer] | ||
| pairMul = zipWith (*) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eta-reduction award 🏆
Solutions for Chapter 1,2, 3 and 4
cc @vrom911