Skip to content

Solutions for Chapter 1,2 & 3 #556

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

Open
wants to merge 36 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
885e820
build: stack.yaml
WolfSoko Feb 23, 2023
bbfbb0e
feat(chapter-1): Task 1 ghci :t types inserted
WolfSoko Feb 23, 2023
f10a336
feat(chapter-1): Task 2 solved
WolfSoko Feb 23, 2023
230e1e3
feat(chapter-1): Task 3 and 4 solved
WolfSoko Feb 23, 2023
6ebc211
feat(chapter-1): Task 5
WolfSoko Feb 23, 2023
5d986b6
feat(chapter-1): solved Task 6
WolfSoko Feb 23, 2023
f4d7b6b
feat(chapter-1): solved Task 7
WolfSoko Feb 23, 2023
cc5b6b6
fix(chapter-1): fixed missing \n Task 1
WolfSoko Feb 23, 2023
2cb8944
fix(chapter-1): Task 3
WolfSoko Feb 23, 2023
1854160
fix(chapter-1): Task 9
WolfSoko Feb 23, 2023
87daf04
fix(chapter-1): Task 9
WolfSoko Feb 23, 2023
6f0082a
fix(chapter-1): extra Task
WolfSoko Feb 24, 2023
ff95475
fix(chapter-1): handle negative numbers
WolfSoko Feb 24, 2023
7c4b137
Merge pull request #1 from WolfSoko/chapter-1
WolfSoko Feb 24, 2023
35a504f
fix(chapter-2): Task 1
WolfSoko Feb 24, 2023
91160f5
fix(chapter-2): Task 2
WolfSoko Feb 24, 2023
91f8ce5
fix(chapter-2): Task 3
WolfSoko Feb 24, 2023
7fb937b
fix(chapter-2): Task 4
WolfSoko Feb 24, 2023
4e8865a
fix(chapter-2): Task 5
WolfSoko Feb 24, 2023
e33eb0d
feat(chapter-2): Task 4
WolfSoko Feb 24, 2023
1255f80
feat(chapter-2): Task 6
WolfSoko Feb 24, 2023
61c71e5
feat(chapter-2): Task 7
WolfSoko Feb 24, 2023
761d07c
fix(chapter-2): Task 8
WolfSoko Feb 24, 2023
7a6aad2
feat(chapter-2): :sparkles: implement Task 9
WolfSoko Feb 24, 2023
b06bd78
feat: :sparkles: impl Task 10
WolfSoko Feb 24, 2023
92529dc
feat: :zap: impl Task 11
WolfSoko Feb 24, 2023
16e5dd3
feat: :sparkles: impl Task 12
WolfSoko Feb 24, 2023
f133a8c
fix(chapter-1): Task 9 no shadowing
WolfSoko Feb 27, 2023
d18d537
feat(chapter-3): Task 1
WolfSoko Feb 27, 2023
eb1bdd5
feat(chapter-3): Task 2 & 3
WolfSoko Feb 27, 2023
2cb5c60
refactor(chapter-2): :sparkles: more consize code
WolfSoko Feb 27, 2023
96748fa
feat(chapter-3): :zap: Task 4
WolfSoko Feb 27, 2023
2932414
feat(chapter-3): :tada: Task 5
WolfSoko Feb 27, 2023
88e7cb1
feat(chapter-3): :fire: impl Task 6
WolfSoko Feb 27, 2023
cbf03ca
feat(chapter-3): :art: impl Task 7
WolfSoko Feb 27, 2023
3fad13c
feat(chapter-3): :sparkles: impl Task 8
WolfSoko Feb 27, 2023
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
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,17 @@ TAGS
# other
.DS_Store
.env
/out/production/learn4haskell/Chapter1.hs
/out/production/learn4haskell/Chapter2.hs
/out/production/learn4haskell/Chapter3.hs
/out/production/learn4haskell/Chapter4.hs
/out/test/learn4haskell/Test/Chapter1.hs
/out/test/learn4haskell/Test/Chapter2.hs
/out/test/learn4haskell/Test/Chapter3.hs
/out/test/learn4haskell/Test/Chapter4.hs
/out/test/learn4haskell/DoctestChapter1.hs
/out/test/learn4haskell/DoctestChapter2.hs
/out/test/learn4haskell/DoctestChapter3.hs
/out/test/learn4haskell/DoctestChapter4.hs
/out/test/learn4haskell/Spec.hs
/stack.yaml
92 changes: 56 additions & 36 deletions src/Chapter1.hs
Original file line number Diff line number Diff line change
Expand Up @@ -209,31 +209,31 @@ So, the output in this example means that 'False' has type 'Bool'.
> 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 @@ expressions in GHCi
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 @@ -428,7 +428,7 @@ task is to specify the type of this function.
>>> squareSum 3 4
49
-}

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


Expand All @@ -449,7 +449,7 @@ Implement the function that takes an integer value and returns the next 'Int'.
function body with the proper implementation.
-}
next :: Int -> Int
next x = error "next: not implemented!"
next x = x + 1

{- |
After you've implemented the function (or even during the implementation), you
Expand Down Expand Up @@ -489,9 +489,8 @@ Implement a function that returns the last digit of a given number.
results. Or you can try to guess the function name, search for it and check
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 = abs n `mod` 10

{- |
=⚔️= Task 6
Expand Down Expand Up @@ -520,7 +519,7 @@ branches because it is an expression and it must always return some value.
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 x else y
Copy link
Member

Choose a reason for hiding this comment

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

() are redundant here. I see how it can be confusing to see when to use them and when not to use, especially in the beginning. But it's usually better to remove redundant brackets for cleaner code 🧹

Suggested change
closestToZero x y = if (abs x) < (abs y) then x else y
closestToZero x y = if abs x < abs y then x else y



{- |
Expand Down Expand Up @@ -553,8 +552,11 @@ value after "=" where the condition is true.

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
| x <= y && y <= z = y
| x >= y && y >= z = y
| otherwise = mid y z x

{- |
=⚔️= Task 8
Expand All @@ -568,7 +570,19 @@ True
>>> isVowel 'x'
False
-}
isVowel c = error "isVowel: not implemented!"
isVowel :: Char -> Bool
isVowel c
| c == 'a' = True
| c == 'e' = True
| c == 'i' = True
| c == 'o' = True
| c == 'u' = True
| c == 'A' = True
| c == 'E' = True
| c == 'I' = True
| c == 'O' = True
| c == 'U' = True
| otherwise = False


{- |
Expand Down Expand Up @@ -631,9 +645,12 @@ Implement a function that returns the sum of the last two digits of a number.
Try to introduce variables in this task (either with let-in or where) to avoid
specifying complex expressions.
-}

sumLast2 n = error "sumLast2: Not implemented!"

sumLast2 :: Int -> Int
sumLast2 n = (lastDigit n) + secondLastDigit
Copy link
Member

Choose a reason for hiding this comment

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

Nice reusage of previous lastDigit function! 👏🏼

I see that you have already a var to represent this bit – lastD, you can reuse it here too!

Suggested change
sumLast2 n = (lastDigit n) + secondLastDigit
sumLast2 n = lastD + secondLastDigit

where
lastTwo = (mod (abs n) 100)
lastD = lastDigit n
secondLastDigit = (lastTwo - lastD) `div` 10

{- |
=💣= Task 10*
Expand All @@ -652,9 +669,12 @@ Implement a function that returns the first digit of a given number.
You need to use recursion in this task. Feel free to return to it later, if you
aren't ready for this boss yet!
-}

firstDigit n = error "firstDigit: Not implemented!"

firstDigit :: Int -> Int
firstDigit n
| absN < 10 = absN
| otherwise = firstDigit (div absN 10)
where
absN = abs n
Copy link
Member

Choose a reason for hiding this comment

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

Very elegant to use where clause here 👍🏼


{-
You did it! Now it is time to open a pull request with your changes
Expand Down
Loading