Conversation
vrom911
left a comment
There was a problem hiding this comment.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 (*) |
Solutions for Chapter 1,2, 3 and 4
cc @vrom911