Skip to content
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

Finished Chapter 1 #571

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 54 additions & 31 deletions src/Chapter1.hs
Original file line number Diff line number Diff line change
Expand Up @@ -209,31 +209,31 @@
> Try to guess first and then compare your expectations with GHCi output

>>> :t True
<INSERT THE RESULT INSTEAD OF THE TEXT>
True :: Bool
>>> :t 'a'
<INSERT THE RESULT INSTEAD OF THE TEXT>
'a' :: Char
>>> :t 42
<INSERT THE RESULT INSTEAD OF THE TEXT>
42 :: Num a => a

A pair of boolean and char:
>>> :t (True, 'x')
<INSERT THE RESULT INSTEAD OF THE TEXT>
(True, 'x') :: (Bool, Char)

Boolean negation:
>>> :t not
<INSERT THE RESULT INSTEAD OF THE TEXT>
not :: Bool -> Bool

Boolean 'and' operator:
>>> :t (&&)
<INSERT THE RESULT INSTEAD OF THE TEXT>
(&&) :: Bool -> Bool -> Bool

Addition of two numbers:
>>> :t (+)
<INSERT THE RESULT INSTEAD OF THE TEXT>
(+) :: Num a => a -> a -> a

Maximum of two values:
>>> :t max
<INSERT THE RESULT INSTEAD OF THE TEXT>
max :: Ord a => a -> a -> a

You might not understand each type at this moment, but don't worry! You've only
started your Haskell journey. Types will become your friends soon.
Expand Down Expand Up @@ -301,43 +301,43 @@
functions and operators first. Remember this from the previous task? ;)

>>> 1 + 2
<INSERT THE RESULT INSTEAD OF THE TEXT>
3

>>> 10 - 15
<INSERT THE RESULT INSTEAD OF THE TEXT>
-5

>>> 10 - (-5) -- negative constants require ()
<INSERT THE RESULT INSTEAD OF THE TEXT>
15

>>> (3 + 5) < 10
<INSERT THE RESULT INSTEAD OF THE TEXT>
True

>>> True && False
<INSERT THE RESULT INSTEAD OF THE TEXT>
False

>>> 10 < 20 || 20 < 5
<INSERT THE RESULT INSTEAD OF THE TEXT>
True

>>> 2 ^ 10 -- power
<INSERT THE RESULT INSTEAD OF THE TEXT>
1024

>>> not False
<INSERT THE RESULT INSTEAD OF THE TEXT>
True

>>> div 20 3 -- integral division
<INSERT THE RESULT INSTEAD OF THE TEXT>
6

>>> mod 20 3 -- integral division remainder
<INSERT THE RESULT INSTEAD OF THE TEXT>
2

>>> max 4 10
<INSERT THE RESULT INSTEAD OF THE TEXT>
10

>>> min 5 (max 1 2)
<INSERT THE RESULT INSTEAD OF THE TEXT>
2

>>> max (min 1 10) (min 5 7)
<INSERT THE RESULT INSTEAD OF THE TEXT>
5

Because Haskell is a __statically-typed__ language, you see an error each time
you try to mix values of different types in situations where you are not
Expand Down Expand Up @@ -429,6 +429,7 @@
49
-}

squareSum :: Int -> Int -> Int
squareSum x y = (x + y) * (x + y)


Expand All @@ -449,7 +450,7 @@
function body with the proper implementation.
-}
next :: Int -> Int
next x = error "next: not implemented!"
next x = (x + 1 )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The brackets are not necessary here

Suggested change
next x = (x + 1 )
next x = x + 1


{- |
After you've implemented the function (or even during the implementation), you
Expand Down Expand Up @@ -490,8 +491,12 @@
whether it works for you!
-}
-- DON'T FORGET TO SPECIFY THE TYPE IN HERE
lastDigit n = error "lastDigit: Not implemented!"

lastDigit :: Int -> Int
lastDigit n
| n < 0 = mod (negate n) 10
| n `mod` 10 == 0 = 0
| otherwise = n `mod` 10
Comment on lines +498 to +499
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! It could be simplified a bit though :)

This is actually could be combined into just one case, because in case of n mod 10 equal 0 it still returns 0 which is covered by just returning n mod 10.

While doing this simplification, you can notice that it actually could be just 1 case if you use abs function on the input 👌🏼


{- |
=⚔️= Task 6
Expand Down Expand Up @@ -519,8 +524,9 @@
👩‍🔬 Due to lazy evaluation in Haskell, only the expression from the branch
satisfying the check will be returned and, therefore, evaluated.
-}

closestToZero :: Int -> Int -> Int
closestToZero x y = error "closestToZero: not implemented!"
closestToZero x y = if abs x > abs y then y else x


{- |
Expand Down Expand Up @@ -554,7 +560,11 @@
Casual reminder about adding top-level type signatures for all functions :)
-}

mid x y z = error "mid: not implemented!"
mid :: Int -> Int -> Int -> Int
mid x y z

Check warning on line 564 in src/Chapter1.hs

View workflow job for this annotation

GitHub Actions / Build Learn4Haskell (3.8, 9.4.4)

Pattern match(es) are non-exhaustive

Check warning on line 564 in src/Chapter1.hs

View workflow job for this annotation

GitHub Actions / Chapter One (3.8, 9.4.4)

Pattern match(es) are non-exhaustive
| (y <= x && x <= z) || (z <= x && x <= y) = x
| (x <= y && y <= z) || (z <= y && y <= x) = y
| (x <= z && z <= y) || (y <= z && z <= x) = z
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we mentioned, the compiler in Haskell is very attentive to the exhaustive pattern-matching. And here it would warn you that Pattern matching is not exhaustive, as the guards have quite complicated logic, and the compiler won't be able to prove that it covers all the cases.

Because of that, you will need to use another guard – | otherwise = ..., to tell the compiler, that your pattern matching is exhaustive 🙂

Suggested change
| (x <= z && z <= y) || (y <= z && z <= x) = z
| otherwise = z


{- |
=⚔️= Task 8
Expand All @@ -568,7 +578,12 @@
>>> isVowel 'x'
False
-}
isVowel c = error "isVowel: not implemented!"

isVowel :: Char -> Bool
isVowel c
| elem c "aeiou" = True
| otherwise = False
Comment on lines +583 to +585
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one! 👍🏼
As elem returns Bool itself, you can just return the result of this function:

isVowel c = elem c "aeiou"

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 🐎




{- |
Expand Down Expand Up @@ -631,9 +646,14 @@
Try to introduce variables in this task (either with let-in or where) to avoid
specifying complex expressions.
-}
sumLast2 :: Int -> Int

sumLast2 n = error "sumLast2: Not implemented!"

sumLast2 n =
let last = if n < 0 then mod (negate n) 100 else mod n 100

Check warning on line 652 in src/Chapter1.hs

View workflow job for this annotation

GitHub Actions / Build Learn4Haskell (3.8, 9.4.4)

This binding for ‘last’ shadows the existing binding

Check warning on line 652 in src/Chapter1.hs

View workflow job for this annotation

GitHub Actions / Chapter One (3.8, 9.4.4)

This binding for ‘last’ shadows the existing binding
first = div last 10
second = mod last 10
Comment on lines +653 to +654
Copy link
Member

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 10

The 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 10

You can see how we could pattern match on the pair 🙂

sumLast = first + second
in sumLast

{- |
=💣= Task 10*
Expand All @@ -653,10 +673,13 @@
aren't ready for this boss yet!
-}

firstDigit n = error "firstDigit: Not implemented!"


firstDigit :: Int -> Int
firstDigit n =
let value = if n < 0 then negate n else n
result = if value >= 10 then firstDigit(div value 10) else value
in result
{-

You did it! Now it is time to open a pull request with your changes
and summon @vrom911 for the review!
-}
Expand Down
Loading