From 9de16d7e2d93f10f9b481043d4a158ff6e2a5129 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Mon, 31 Oct 2022 22:35:50 -0300 Subject: [PATCH 01/36] docs: Task 1 done --- src/Chapter1.hs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Chapter1.hs b/src/Chapter1.hs index 406deeaca..a1144f9c9 100644 --- a/src/Chapter1.hs +++ b/src/Chapter1.hs @@ -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 - +True :: Bool >>> :t 'a' - +'a' :: Char >>> :t 42 - +42 :: Num a => a A pair of boolean and char: >>> :t (True, 'x') - +(True, 'x') :: (Bool, Char) Boolean negation: >>> :t not - +not :: Bool -> Bool Boolean 'and' operator: >>> :t (&&) - +(&&) :: Bool -> Bool -> Bool Addition of two numbers: >>> :t (+) - +(+) :: Num a => a -> a -> a Maximum of two values: >>> :t max - +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. From e7b52c6ea54fb73fe342c42070067b2836bb0e3c Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Mon, 31 Oct 2022 22:48:10 -0300 Subject: [PATCH 02/36] docs: Charter 1 - Task 2 done --- src/Chapter1.hs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Chapter1.hs b/src/Chapter1.hs index a1144f9c9..422c77502 100644 --- a/src/Chapter1.hs +++ b/src/Chapter1.hs @@ -301,43 +301,43 @@ expressions in GHCi functions and operators first. Remember this from the previous task? ;) >>> 1 + 2 - +3 >>> 10 - 15 - +-5 >>> 10 - (-5) -- negative constants require () - +15 >>> (3 + 5) < 10 - +True >>> True && False - +False >>> 10 < 20 || 20 < 5 - +True >>> 2 ^ 10 -- power - +1024 >>> not False - +True >>> div 20 3 -- integral division - +6 >>> mod 20 3 -- integral division remainder - +2 >>> max 4 10 - +10 >>> min 5 (max 1 2) - +2 >>> max (min 1 10) (min 5 7) - +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 From 1dc7fceddf90f63d233fae6f1a735385c845a13d Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Mon, 31 Oct 2022 22:57:35 -0300 Subject: [PATCH 03/36] docs: Charter 1 - Task 3 done --- src/Chapter1.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Chapter1.hs b/src/Chapter1.hs index 422c77502..f91d50cbc 100644 --- a/src/Chapter1.hs +++ b/src/Chapter1.hs @@ -428,7 +428,7 @@ task is to specify the type of this function. >>> squareSum 3 4 49 -} - +squareSum :: Int a => a -> a -> a squareSum x y = (x + y) * (x + y) From d89747d15b05e170efc6f7158a30b3d224a7bb7d Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Mon, 31 Oct 2022 23:01:12 -0300 Subject: [PATCH 04/36] docs: Charter 1 - Task 3 and 4 done --- src/Chapter1.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Chapter1.hs b/src/Chapter1.hs index f91d50cbc..0fbaadd60 100644 --- a/src/Chapter1.hs +++ b/src/Chapter1.hs @@ -428,7 +428,7 @@ task is to specify the type of this function. >>> squareSum 3 4 49 -} -squareSum :: Int a => a -> a -> a +squareSum :: Int -> Int -> Int squareSum x y = (x + y) * (x + y) @@ -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 From 1d04f0dd0a97be750c2fc1b0db2a2f4f9be2849b Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Mon, 31 Oct 2022 23:23:38 -0300 Subject: [PATCH 05/36] docs: Charter 1 - Task 5, 6, 7 and 8 --- src/Chapter1.hs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/Chapter1.hs b/src/Chapter1.hs index 0fbaadd60..f3904bbfd 100644 --- a/src/Chapter1.hs +++ b/src/Chapter1.hs @@ -490,7 +490,8 @@ Implement a function that returns the last digit of a given number. 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 = mod n 10 {- | @@ -520,7 +521,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 {- | @@ -553,8 +554,14 @@ 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 && x < z && z < y = z + | x < y && x < z && y < z = y + | z < x && z < y && x < y = x + | z < x && z < y && y < x = y + | y < x && y < z && x < z = x + | otherwise = z {- | =⚔️= Task 8 @@ -568,7 +575,14 @@ 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 + | otherwise = False {- | From 320bc4da8ef480f3dda35cb3580674e1f1e61da3 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Mon, 31 Oct 2022 23:44:00 -0300 Subject: [PATCH 06/36] docs: Charter 1 - Task 9 and boss --- src/Chapter1.hs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Chapter1.hs b/src/Chapter1.hs index f3904bbfd..9a169bf87 100644 --- a/src/Chapter1.hs +++ b/src/Chapter1.hs @@ -646,7 +646,14 @@ 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 = mod10 (div10 n) + mod10 n + where + div10 :: Int -> Int + div10 x = div x 10 + + mod10 :: Int -> Int + mod10 x = mod x 10 {- | @@ -667,7 +674,10 @@ 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 = if n < 10 + then n + else firstDigit (n `div` 10) {- From 9a1e01ebbb2dfcb369f137f8aff8fa497bffdccf Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Wed, 2 Nov 2022 11:03:26 -0300 Subject: [PATCH 07/36] docs: Charter 2 - Task 1 in comments --- src/Chapter2.hs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Chapter2.hs b/src/Chapter2.hs index b98ceaf7d..d3b702eb8 100644 --- a/src/Chapter2.hs +++ b/src/Chapter2.hs @@ -136,26 +136,27 @@ functions in GHCi and insert the corresponding resulting output below: List of booleans: >>> :t [True, False] - +[True, False] :: [Bool] String is a list of characters: >>> :t "some string" - +"some string" :: String Empty list: >>> :t [] - +[] :: [a] Append two lists: >>> :t (++) - +(++) :: [a] -> [a] -> [a] Prepend an element at the beginning of a list: >>> :t (:) - +(:) :: a -> [a] -> [a] Reverse a list: >>> :t reverse +reverse :: [a] -> [a] Take first N elements of a list: @@ -164,15 +165,15 @@ Take first N elements of a list: Create a list from N same elements: >>> :t replicate - +replicate :: Int -> a -> [a] Split a string by line breaks: >>> :t lines - +lines :: String -> [String] Join a list of strings with line breaks: >>> :t unlines - +unlines :: [String] -> String -} From c9ca63b7ecaff6e6741ae6224a88bad771ded9de Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Wed, 2 Nov 2022 11:28:41 -0300 Subject: [PATCH 08/36] docs: Charter 2 - Task 2 in comments --- src/Chapter2.hs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Chapter2.hs b/src/Chapter2.hs index d3b702eb8..b794575e2 100644 --- a/src/Chapter2.hs +++ b/src/Chapter2.hs @@ -187,32 +187,43 @@ Evaluate the following expressions in GHCi and insert the answers. Try to guess first, what you will see. >>> [10, 2] ++ [3, 1, 5] +[10,2,3,1,5] >>> [] ++ [1, 4] -- [] is an empty list +[1,4] >>> 3 : [1, 2] +[3,1,2] >>> 4 : 2 : [5, 10] -- prepend multiple elements +[4,2,5,10] >>> [1 .. 10] -- list ranges +[1,2,3,4,5,6,7,8,9,10] >>> [10 .. 1] +[] >>> [10, 9 .. 1] -- backwards list with explicit step +[10,9,8,7,6,5,4,3,2,1] >>> length [4, 10, 5] -- list length +3 >>> replicate 5 True +[True,True,True,True,True] >>> take 5 "Hello, World!" +"Hello" >>> drop 5 "Hello, World!" +", World!" >>> zip "abc" [1, 2, 3] -- convert two lists to a single list of pairs +[('a',1),('b',2),('c',3)] >>> words "Hello Haskell World!" -- split the string into the list of words - - +["Hello","Haskell","World!"] 👩‍🔬 Haskell has a lot of syntax sugar. In the case with lists, any list literal like "[3, 1, 2]" is syntax sugar for prepending elements From e3fbc7a6e8b897174dec210176314a2c481db27f Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Wed, 2 Nov 2022 14:07:59 -0300 Subject: [PATCH 09/36] docs: Charter 2 - Task 3, 4 and 5 --- src/Chapter2.hs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Chapter2.hs b/src/Chapter2.hs index b794575e2..493c99834 100644 --- a/src/Chapter2.hs +++ b/src/Chapter2.hs @@ -348,7 +348,9 @@ from it! ghci> :l src/Chapter2.hs -} subList :: Int -> Int -> [a] -> [a] -subList = error "subList: Not implemented!" +subList _ _ [] = [] +subList x 0 y = [] +subList x y b = take (y-x+1) $ drop x b {- | =⚔️= Task 4 @@ -361,7 +363,10 @@ Implement a function that returns only the first half of a given list. "b" -} -- PUT THE FUNCTION TYPE IN HERE -firstHalf l = error "firstHalf: Not implemented!" + +firstHalf :: [a] -> [a] +firstHalf [] = [] +firstHalf a = take ((length a) `div` 2) a {- | @@ -513,7 +518,9 @@ True >>> isThird42 [42, 42, 0, 42] False -} -isThird42 = error "isThird42: Not implemented!" +isThird42 :: (Eq a, Num a) => [a] -> Bool +isThird42 [] = False +isThird42 ( _ : _ : x : xs ) = if x == 42 then True else False {- | From 0108694c393ec2d42b4829f929cc58efc9f734b9 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Wed, 2 Nov 2022 17:32:35 -0300 Subject: [PATCH 10/36] docs: Charter 2 - Task 6 and 7 --- src/Chapter2.hs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Chapter2.hs b/src/Chapter2.hs index 493c99834..837ceed0f 100644 --- a/src/Chapter2.hs +++ b/src/Chapter2.hs @@ -625,7 +625,8 @@ Implement a function that duplicates each element of the list -} duplicate :: [a] -> [a] -duplicate = error "duplicate: Not implemented!" +duplicate [] = [] +duplicate (x:xs) = x : x : duplicate xs {- | @@ -640,7 +641,15 @@ Write a function that takes elements of a list only in even positions. >>> takeEven [2, 1, 3, 5, 4] [2,3,4] -} -takeEven = error "takeEven: Not implemented!" +takeEven :: [a] -> [a] +takeEven [] =[] +takeEven (x:xs) = recursiveEven 0 (x : xs) + where + recursiveEven :: Int -> [a] -> [a] + recursiveEven _ [] = [] + recursiveEven c (x:xs) = if mod c 2 == 0 + then x : recursiveEven (c+1) xs + else recursiveEven (c+1) xs {- | =🛡= Higher-order functions From 4ff62646cfd71c2c79ec0dbf07695e5f6ee4de58 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Wed, 2 Nov 2022 18:49:31 -0300 Subject: [PATCH 11/36] docs: Charter 2 - Task 8 and 9 --- src/Chapter2.hs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Chapter2.hs b/src/Chapter2.hs index 837ceed0f..305109995 100644 --- a/src/Chapter2.hs +++ b/src/Chapter2.hs @@ -755,8 +755,13 @@ value of the element itself 🕯 HINT: Use combination of 'map' and 'replicate' -} +-- smartReplicate :: [Int] -> [Int] +-- smartReplicate [] = [] +-- smartReplicate (x:xs) = (replicate x x) ++ smartReplicate xs +-- dont understod how to use map smartReplicate arr = map (\x -> replicate x x) arr + smartReplicate :: [Int] -> [Int] -smartReplicate l = error "smartReplicate: Not implemented!" +smartReplicate = concatMap (\x -> replicate x x) {- | =⚔️= Task 9 @@ -769,8 +774,12 @@ the list with only those lists that contain a passed element. 🕯 HINT: Use the 'elem' function to check whether an element belongs to a list -} -contains = error "contains: Not implemented!" - +contains :: Int -> [[Int]] -> [Int] +contains _ [] = [] +contains _ [[]] = [] +contains b (x:xs) = if (elem b x) == True + then x ++ contains b xs + else contains b xs {- | =🛡= Eta-reduction From 0543601bd97802fbfdb8cb2d7869fe82e863d33a Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Wed, 2 Nov 2022 18:57:57 -0300 Subject: [PATCH 12/36] docs: Charter 2 - Task 10 --- src/Chapter2.hs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Chapter2.hs b/src/Chapter2.hs index 305109995..56fb85c07 100644 --- a/src/Chapter2.hs +++ b/src/Chapter2.hs @@ -818,13 +818,15 @@ Let's now try to eta-reduce some of the functions and ensure that we mastered the skill of eta-reducing. -} divideTenBy :: Int -> Int -divideTenBy x = div 10 x +divideTenBy = div 10 -- TODO: type ;) -listElementsLessThan x l = filter (< x) l +listElementsLessThan :: Int -> [Int] -> [Int] +listElementsLessThan x = filter (< x) -- Can you eta-reduce this one??? -pairMul xs ys = zipWith (*) xs ys +pairMul :: [Int] -> [Int] -> [Int] +pairMul = zipWith (*) {- | =🛡= Lazy evaluation From bc1d97618ce7408803e80334945b4eec40c77f23 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Wed, 2 Nov 2022 23:52:39 -0300 Subject: [PATCH 13/36] docs: Charter 2 - Task 11 and 12 --- src/Chapter2.hs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Chapter2.hs b/src/Chapter2.hs index 56fb85c07..f1770ecb9 100644 --- a/src/Chapter2.hs +++ b/src/Chapter2.hs @@ -881,7 +881,9 @@ list. 🕯 HINT: Use the 'cycle' function -} -rotate = error "rotate: Not implemented!" +rotate :: Int -> [Int] -> [Int] +rotate _ [] = [] +rotate n arr = drop n $ take ((length arr) + n) $ cycle arr {- | =💣= Task 12* @@ -897,7 +899,9 @@ and reverses it. function, but in this task, you need to implement it manually. No cheating! -} -rewind = error "rewind: Not Implemented!" +rewind :: [Int] -> [Int] +rewind [] = [] +rewind (x:xs) = (rewind xs) ++ [x] {- From 29df2f6583f0e63588cf85febd9d408e3d39ecfa Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Sat, 19 Nov 2022 17:49:24 -0300 Subject: [PATCH 14/36] fix: Charter 1 - review solutions --- src/Chapter1.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Chapter1.hs b/src/Chapter1.hs index 9a169bf87..7472ddc18 100644 --- a/src/Chapter1.hs +++ b/src/Chapter1.hs @@ -491,7 +491,7 @@ Implement a function that returns the last digit of a given number. -} -- DON'T FORGET TO SPECIFY THE TYPE IN HERE lastDigit :: Int -> Int -lastDigit n = mod n 10 +lastDigit n = mod (abs n) 10 {- | From e6b6a8919a82ec32e4718b50127a90811428ac94 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Mon, 21 Nov 2022 21:37:41 -0300 Subject: [PATCH 15/36] fix: run unit test to test and fix --- src/Chapter1.hs | 11 +++++------ src/Chapter2.hs | 42 ++++++++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/Chapter1.hs b/src/Chapter1.hs index 7472ddc18..416d57bb1 100644 --- a/src/Chapter1.hs +++ b/src/Chapter1.hs @@ -556,7 +556,6 @@ Casual reminder about adding top-level type signatures for all functions :) -} mid :: Int -> Int -> Int -> Int mid x y z - | x < y && x < z && z < y = z | x < y && x < z && y < z = y | z < x && z < y && x < y = x | z < x && z < y && y < x = y @@ -650,10 +649,10 @@ sumLast2 :: Int -> Int sumLast2 n = mod10 (div10 n) + mod10 n where div10 :: Int -> Int - div10 x = div x 10 + div10 x = div (abs x) 10 mod10 :: Int -> Int - mod10 x = mod x 10 + mod10 x = mod (abs x) 10 {- | @@ -675,9 +674,9 @@ aren't ready for this boss yet! -} firstDigit :: Int -> Int -firstDigit n = if n < 10 - then n - else firstDigit (n `div` 10) +firstDigit n = if abs n < 10 + then abs n + else firstDigit (abs n `div` 10) {- diff --git a/src/Chapter2.hs b/src/Chapter2.hs index f1770ecb9..f2b756568 100644 --- a/src/Chapter2.hs +++ b/src/Chapter2.hs @@ -349,8 +349,8 @@ ghci> :l src/Chapter2.hs -} subList :: Int -> Int -> [a] -> [a] subList _ _ [] = [] -subList x 0 y = [] -subList x y b = take (y-x+1) $ drop x b +subList _ 0 _ = [] +subList x y b = take (y - x + 1) $ drop x b {- | =⚔️= Task 4 @@ -520,7 +520,9 @@ False -} isThird42 :: (Eq a, Num a) => [a] -> Bool isThird42 [] = False -isThird42 ( _ : _ : x : xs ) = if x == 42 then True else False +isThird42 [_] = False +isThird42 [_, _] = False +isThird42 ( _ : _ : x : _ ) = x == 42 {- | @@ -641,15 +643,27 @@ Write a function that takes elements of a list only in even positions. >>> takeEven [2, 1, 3, 5, 4] [2,3,4] -} +-- takeEven :: [a] -> [a] +-- takeEven [] = [] +-- takeEven (x:xs) = recursiveEven 0 (x : xs) +-- where +-- recursiveEven :: Int -> [a] -> [a] +-- recursiveEven _ [] = [] +-- recursiveEven c (x:xs) = if mod c 2 == 0 +-- then x : recursiveEven (c + 1) xs +-- else recursiveEven (c + 1) xs takeEven :: [a] -> [a] -takeEven [] =[] -takeEven (x:xs) = recursiveEven 0 (x : xs) - where - recursiveEven :: Int -> [a] -> [a] - recursiveEven _ [] = [] - recursiveEven c (x:xs) = if mod c 2 == 0 - then x : recursiveEven (c+1) xs - else recursiveEven (c+1) xs +takeEven [] = [] +takeEven [_] = [] +takeEven ( x : _ : xs ) = [x] ++ takeEven xs + +-- isThird42 :: (Eq a, Num a) => [a] -> Bool +-- isThird42 [] = False +-- isThird42 [_] = False +-- isThird42 [_, _] = False +-- isThird42 ( _ : _ : x : _ ) = if x == 42 then True else False + + {- | =🛡= Higher-order functions @@ -774,11 +788,11 @@ the list with only those lists that contain a passed element. 🕯 HINT: Use the 'elem' function to check whether an element belongs to a list -} -contains :: Int -> [[Int]] -> [Int] +contains :: Int -> [[Int]] -> [[Int]] contains _ [] = [] contains _ [[]] = [] contains b (x:xs) = if (elem b x) == True - then x ++ contains b xs + then [x] ++ contains b xs else contains b xs {- | @@ -899,7 +913,7 @@ and reverses it. function, but in this task, you need to implement it manually. No cheating! -} -rewind :: [Int] -> [Int] +rewind :: [a] -> [a] rewind [] = [] rewind (x:xs) = (rewind xs) ++ [x] From c059035c050c117c038d588814988c916436fc0f Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Mon, 21 Nov 2022 21:53:28 -0300 Subject: [PATCH 16/36] fix: run unit test to test and fix - from charter 2 --- src/Chapter2.hs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Chapter2.hs b/src/Chapter2.hs index f2b756568..611b1e517 100644 --- a/src/Chapter2.hs +++ b/src/Chapter2.hs @@ -349,8 +349,11 @@ ghci> :l src/Chapter2.hs -} subList :: Int -> Int -> [a] -> [a] subList _ _ [] = [] +subList 0 0 b = take 1 b subList _ 0 _ = [] -subList x y b = take (y - x + 1) $ drop x b +subList x y b = if x >= 0 + then take (y - x + 1) $ drop x b + else [] {- | =⚔️= Task 4 @@ -654,16 +657,9 @@ Write a function that takes elements of a list only in even positions. -- else recursiveEven (c + 1) xs takeEven :: [a] -> [a] takeEven [] = [] -takeEven [_] = [] +takeEven [x] = [x] takeEven ( x : _ : xs ) = [x] ++ takeEven xs --- isThird42 :: (Eq a, Num a) => [a] -> Bool --- isThird42 [] = False --- isThird42 [_] = False --- isThird42 [_, _] = False --- isThird42 ( _ : _ : x : _ ) = if x == 42 then True else False - - {- | =🛡= Higher-order functions From ed58cee9d9a803be2f8a4f579e7290fef3cedd21 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Mon, 21 Nov 2022 22:13:17 -0300 Subject: [PATCH 17/36] doc: charter 2 take --- src/Chapter2.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Chapter2.hs b/src/Chapter2.hs index 611b1e517..d652f4c69 100644 --- a/src/Chapter2.hs +++ b/src/Chapter2.hs @@ -161,7 +161,7 @@ reverse :: [a] -> [a] Take first N elements of a list: >>> :t take - +take :: Int -> [a] -> [a] Create a list from N same elements: >>> :t replicate From bd324a939d75e40747e26f25e3e58b519f62458d Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Sun, 27 Nov 2022 18:42:21 -0300 Subject: [PATCH 18/36] feat: charter 3 task 1 --- src/Chapter3.hs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Chapter3.hs b/src/Chapter3.hs index 061811064..6acafc8d6 100644 --- a/src/Chapter3.hs +++ b/src/Chapter3.hs @@ -344,6 +344,26 @@ of a book, but you are not limited only by the book properties we described. Create your own book type of your dreams! -} +data Book = MkBook + { bookName :: String + , bookCover :: String + , bookAuthor :: String + , bookLanguage :: String + , bookPages :: Int + , bookRating :: Int + } deriving (Show) + +{- +livrinho = MkBook + { bookName = "meu livro" + , bookCover = "wow" + , bookAuthor = "Adriano Waltrick" + , bookLanguage = "Portuguese" + , bookPages = 100 + , bookRating = 10 + } +-} + {- | =⚔️= Task 2 From 522bc307dfab0434638f0085f5d6cd44ebd8e91a Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Mon, 5 Dec 2022 19:42:31 -0300 Subject: [PATCH 19/36] feat: task 4 - incomplete --- src/Chapter3.hs | 89 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/src/Chapter3.hs b/src/Chapter3.hs index 6acafc8d6..0884845f5 100644 --- a/src/Chapter3.hs +++ b/src/Chapter3.hs @@ -51,7 +51,9 @@ provide more top-level type signatures, especially when learning Haskell. -} {-# LANGUAGE InstanceSigs #-} -module Chapter3 where +-- Adriano comentou isso +-- module Chapter3 where +-- import Distribution.PackageDescription (Library) {- =🛡= Types in Haskell @@ -396,6 +398,40 @@ after the fight. The battle has the following possible outcomes: -} +data Knight = MkKnight + { health :: Int + , attack :: Int + , gold :: Int + } deriving (Show) + + +data Monster = MkMonster + { mHealth :: Int + , mAttack :: Int + , mGold :: Int + } deriving (Show) + +fighter1 :: Knight +fighter1 = MkKnight + { health = 100 + , attack = 10 + , gold = 0 + } + +dragon1 :: Monster +dragon1 = MkMonster + { mHealth = 10 + , mAttack = 10 + , mGold = 10 + } + +fight :: Monster -> Knight -> Int +fight monster knight + | mHealth monster <= 0 = gold knight + mGold monster + | health knight <= 0 = -1 + | otherwise = fight (MkMonster (mHealth monster - attack knight) (mAttack monster) (mGold monster)) (MkKnight (health knight - mAttack monster) (attack knight) (gold knight)) + + {- | =🛡= Sum types @@ -482,6 +518,14 @@ Create a simple enumeration for the meal types (e.g. breakfast). The one who comes up with the most number of names wins the challenge. Use your creativity! -} +data MealType + = Nescau + | PaoComLeite + | BolachaSalgada + | BolachaDoce + | Biscoito + | Brigadeiro + {- | =⚔️= Task 4 @@ -502,6 +546,49 @@ After defining the city, implement the following functions: and at least 10 living __people__ inside in all houses of the city in total. -} +data Castle = MkCastle + { castleName :: String + } deriving (Show) + +data Wall = MkWall + { size :: Int + } deriving (Show) + +data ChurchData = MkChurch + { churchName :: String + } deriving (Show) + +data LibraryData = MkLibrary + { libraryName :: String + } deriving (Show) + +data ChurchOrLibrary + = Church ChurchData + | Library LibraryData + deriving (Show) + +data House = MkHouse + { people :: Int + } deriving (Show) + +data City = MkCity + { castle :: Castle + , wall :: Wall + , churchOrLibrary :: ChurchOrLibrary + , houses :: [House] + } deriving (Show) + + +igreja1 :: ChurchOrLibrary +igreja1 = Church (MkChurch "Igreja1") + +buildCastle :: City -> String -> City +buildCastle city name = MkCity (MkCastle name) + (MkWall 10) + igreja1 + [MkHouse 1, MkHouse 2, MkHouse 3, MkHouse 4] + + {- =🛡= Newtypes From 372a36a02c4c3c6c131a5f1a1e29fafe8d2a0dc4 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Fri, 9 Dec 2022 07:22:19 -0300 Subject: [PATCH 20/36] tentativa de resolucao --- src/Chapter3.hs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Chapter3.hs b/src/Chapter3.hs index 0884845f5..410b96e6e 100644 --- a/src/Chapter3.hs +++ b/src/Chapter3.hs @@ -677,8 +677,11 @@ data Player = Player , playerStrength :: Int } -calculatePlayerDamage :: Int -> Int -> Int -calculatePlayerDamage attack strength = attack + strength +newtype PlayerAttack = MkPlayerAttack Int +newtype PlayerStrength = MkPlayerStrength Int + +calculatePlayerDamage :: PlayerAttack -> PlayerStrength -> Int +calculatePlayerDamage (MkPlayerAttack a) (MkPlayerStrength s) = a + s calculatePlayerDefense :: Int -> Int -> Int calculatePlayerDefense armor dexterity = armor * dexterity @@ -690,8 +693,8 @@ calculatePlayerHit damage defense health = health + defense - damage hitPlayer :: Player -> Player -> Player hitPlayer player1 player2 = let damage = calculatePlayerDamage - (playerAttack player2) - (playerStrength player2) + (MkPlayerAttack (playerAttack player2)) + (MkPlayerStrength (playerStrength player2)) defense = calculatePlayerDefense (playerArmor player1) (playerDexterity player1) From af76b02272f26f189ca5935b807cfab6a993bb45 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Fri, 9 Dec 2022 21:11:52 +0000 Subject: [PATCH 21/36] wip: task 4 - very hard --- .gitignore | 1 + src/Chapter3.hs | 66 +++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 3b5dbd594..4f5eb7387 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,4 @@ TAGS # other .DS_Store .env +Dockerfile \ No newline at end of file diff --git a/src/Chapter3.hs b/src/Chapter3.hs index 410b96e6e..e6a020330 100644 --- a/src/Chapter3.hs +++ b/src/Chapter3.hs @@ -364,6 +364,8 @@ livrinho = MkBook , bookPages = 100 , bookRating = 10 } + +livrinho = MkBook { bookName = "meu livro", bookCover = "wow", bookAuthor = "Adriano Waltrick", bookLanguage = "Portuguese", bookPages = 100, bookRating = 10} -} {- | @@ -523,6 +525,7 @@ data MealType | PaoComLeite | BolachaSalgada | BolachaDoce + | BolachaRecheada | Biscoito | Brigadeiro @@ -548,7 +551,7 @@ After defining the city, implement the following functions: data Castle = MkCastle { castleName :: String - } deriving (Show) + } deriving (Eq, Show) data Wall = MkWall { size :: Int @@ -567,27 +570,70 @@ data ChurchOrLibrary | Library LibraryData deriving (Show) +data PeopleInsideHouse + = None + | One + | Two + | Three + | Four + deriving (Show, Eq, Ord, Enum) + data House = MkHouse - { people :: Int + { people :: PeopleInsideHouse } deriving (Show) data City = MkCity - { castle :: Castle - , wall :: Wall - , churchOrLibrary :: ChurchOrLibrary + { castle :: Maybe Castle + , wall :: Maybe Wall + , churchOrLibrary :: Maybe ChurchOrLibrary , houses :: [House] } deriving (Show) - igreja1 :: ChurchOrLibrary igreja1 = Church (MkChurch "Igreja1") buildCastle :: City -> String -> City -buildCastle city name = MkCity (MkCastle name) - (MkWall 10) - igreja1 - [MkHouse 1, MkHouse 2, MkHouse 3, MkHouse 4] +buildCastle (MkCity xcastle xwall xchurchOrLibrary xhouses) name = + if xcastle == Nothing then MkCity (Just (MkCastle name)) Nothing Nothing [] + else MkCity (Just (MkCastle name)) xwall xchurchOrLibrary xhouses + +brasilCastle :: Castle +brasilCastle = MkCastle "Brasil Castle" + +argentinaCastle :: Castle +argentinaCastle = MkCastle "Argentina Castle" + +saoPaulo :: City +saoPaulo = (MkCity (Just brasilCastle) (Just (MkWall 3)) (Just igreja1) [(MkHouse One)]) + +novoCastelo :: City +novoCastelo = buildCastle saoPaulo "Novo Nome" + +buildHouse :: City -> PeopleInsideHouse -> City +buildHouse (MkCity xcastle xwall xchurchOrLibrary xhouses) p = + MkCity xcastle xwall xchurchOrLibrary (xhouses ++ [(MkHouse p)]) + +{- buildHouse saoPaulo Two -} + +{- +✦ buildWalls — build walls in the city. But since building walls is a + complicated task, walls can be built only if the city has a castle + and at least 10 living __people__ inside in all houses of the city in total. +-} + +countPeoples :: City -> Int +countPeoples (MkCity xcastle xwall xchurchOrLibrary []) = 0 +countPeoples (MkCity xcastle xwall xchurchOrLibrary ((MkHouse p):xs)) = + (fromEnum p) + (countPeoples (MkCity xcastle xwall xchurchOrLibrary xs)) + +countPeoplesArray :: [House] -> Int +countPeoplesArray [] = 0 +countPeoplesArray ((MkHouse p):xs) = (fromEnum p) + countPeoplesArray xs +buildWalls :: City -> Int -> Maybe City +buildWalls (MkCity xcastle (Just (MkWall iwall)) xchurchOrLibrary xhouses) nwalls = + if xcastle == Nothing || (countPeoplesArray xhouses) < 10 then Nothing + else Just (MkCity xcastle (Just (MkWall (nwalls + iwall))) xchurchOrLibrary xhouses) {- =🛡= Newtypes From ee29b5a2a886215a07db549bf51e9aba0c4e08e9 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Thu, 5 Jan 2023 22:02:29 -0300 Subject: [PATCH 22/36] feat provocation of vrom911 for divMod - hard stuff --- src/Chapter1.hs | 6 ++++++ src/Chapter4.hs | 23 ++++++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/Chapter1.hs b/src/Chapter1.hs index 416d57bb1..2a01629e0 100644 --- a/src/Chapter1.hs +++ b/src/Chapter1.hs @@ -654,6 +654,12 @@ sumLast2 n = mod10 (div10 n) + mod10 n mod10 :: Int -> Int mod10 x = mod (abs x) 10 +sumLast2' :: (Integral a, Num a) => a -> a +sumLast2' n = mdiv10 + mod1 + where + mdiv10 = mod c 10 + mod1 = d + (c, d) = divMod (abs n) 10 {- | =💣= Task 10* diff --git a/src/Chapter4.hs b/src/Chapter4.hs index caec5a95d..e794a881d 100644 --- a/src/Chapter4.hs +++ b/src/Chapter4.hs @@ -281,7 +281,6 @@ data Secret e a | Reward a deriving (Show, Eq) - {- | Functor works with types that have kind `* -> *` but our 'Secret' has kind `* -> * -> *`. What should we do? Don't worry. We can partially @@ -291,8 +290,10 @@ we can reuse already known concepts (e.g. partial application) from values and apply them to the type level? -} instance Functor (Secret e) where - fmap :: (a -> b) -> Secret e a -> Secret e b - fmap = error "fmap for Box: not implemented!" + fmap :: (a -> b) -> Secret e a -> Secret e b + fmap _ (Trap e) = Trap e + fmap f (Reward a) = Reward (f a) +-- fmap (++"teste2") a {- | =⚔️= Task 3 @@ -469,12 +470,12 @@ Applicatives can be found in many applications: Implement the Applicative instance for our 'Secret' data type from before. -} -instance Applicative (Secret e) where - pure :: a -> Secret e a - pure = error "pure Secret: Not implemented!" +-- instance Applicative (Secret e) where +-- pure :: a -> Secret e a +-- pure = error "pure Secret: Not implemented!" - (<*>) :: Secret e (a -> b) -> Secret e a -> Secret e b - (<*>) = error "(<*>) Secret: Not implemented!" +-- (<*>) :: Secret e (a -> b) -> Secret e a -> Secret e b +-- (<*>) = error "(<*>) Secret: Not implemented!" {- | =⚔️= Task 5 @@ -597,9 +598,9 @@ concepts in the end. Implement the 'Monad' instance for our 'Secret' type. -} -instance Monad (Secret e) where - (>>=) :: Secret e a -> (a -> Secret e b) -> Secret e b - (>>=) = error "bind Secret: Not implemented!" +-- instance Monad (Secret e) where +-- (>>=) :: Secret e a -> (a -> Secret e b) -> Secret e b +-- (>>=) = error "bind Secret: Not implemented!" {- | =⚔️= Task 7 From aed9e03d1fba87e582f98eb84b0684550ca2da6e Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Thu, 5 Jan 2023 22:34:11 -0300 Subject: [PATCH 23/36] fix: rewind function now use cons : --- src/Chapter2.hs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Chapter2.hs b/src/Chapter2.hs index d652f4c69..0d0438a68 100644 --- a/src/Chapter2.hs +++ b/src/Chapter2.hs @@ -891,7 +891,7 @@ list. 🕯 HINT: Use the 'cycle' function -} -rotate :: Int -> [Int] -> [Int] +rotate :: Int -> [a] -> [a] rotate _ [] = [] rotate n arr = drop n $ take ((length arr) + n) $ cycle arr @@ -909,10 +909,16 @@ and reverses it. function, but in this task, you need to implement it manually. No cheating! -} +rewind' :: [a] -> [a] +rewind' [] = [] +rewind' (x:xs) = (rewind' xs) ++ [x] + + rewind :: [a] -> [a] rewind [] = [] -rewind (x:xs) = (rewind xs) ++ [x] - +rewind arr = head pegaproximo : rewind (tail pegaproximo) + where + pegaproximo = rotate (length arr - 1) arr {- You did it! Now it is time to open pull request with your changes From ee075a6d1950f28140adb0f794f4774352daad2b Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Sat, 7 Jan 2023 13:50:51 -0300 Subject: [PATCH 24/36] feat task 7 - Gold and List --- src/Chapter3.hs | 52 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/src/Chapter3.hs b/src/Chapter3.hs index e6a020330..75c5f4db1 100644 --- a/src/Chapter3.hs +++ b/src/Chapter3.hs @@ -51,8 +51,8 @@ provide more top-level type signatures, especially when learning Haskell. -} {-# LANGUAGE InstanceSigs #-} --- Adriano comentou isso --- module Chapter3 where +module Chapter3 where +-- import LearnHaskell (TreasureChest(TreasureChest)) -- import Distribution.PackageDescription (Library) {- @@ -622,7 +622,7 @@ buildHouse (MkCity xcastle xwall xchurchOrLibrary xhouses) p = -} countPeoples :: City -> Int -countPeoples (MkCity xcastle xwall xchurchOrLibrary []) = 0 +countPeoples (MkCity _ _ _ []) = 0 countPeoples (MkCity xcastle xwall xchurchOrLibrary ((MkHouse p):xs)) = (fromEnum p) + (countPeoples (MkCity xcastle xwall xchurchOrLibrary xs)) @@ -631,8 +631,12 @@ countPeoplesArray [] = 0 countPeoplesArray ((MkHouse p):xs) = (fromEnum p) + countPeoplesArray xs buildWalls :: City -> Int -> Maybe City +buildWalls (MkCity (Just (MkCastle _)) Nothing (Just _) []) _ = Nothing +buildWalls (MkCity Nothing Nothing Nothing []) _ = Nothing +buildWalls (MkCity Nothing _ _ []) _ = Nothing +buildWalls (MkCity (Just _) Nothing Nothing []) _ = Nothing buildWalls (MkCity xcastle (Just (MkWall iwall)) xchurchOrLibrary xhouses) nwalls = - if xcastle == Nothing || (countPeoplesArray xhouses) < 10 then Nothing + if countPeoplesArray xhouses < 10 then Nothing else Just (MkCity xcastle (Just (MkWall (nwalls + iwall))) xchurchOrLibrary xhouses) {- @@ -733,7 +737,7 @@ calculatePlayerDefense :: Int -> Int -> Int calculatePlayerDefense armor dexterity = armor * dexterity calculatePlayerHit :: Int -> Int -> Int -> Int -calculatePlayerHit damage defense health = health + defense - damage +calculatePlayerHit damage defense health1 = health1 + defense - damage -- The second player hits first player and the new first player is returned hitPlayer :: Player -> Player -> Player @@ -911,6 +915,22 @@ parametrise data types in places where values can be of any general type. maybe-treasure ;) -} +data DragonData = MkDragon + { magicPower :: Int + } deriving (Show) + +data TreasureChestData a = MkTreasureChest + { goldOnChest :: a + } deriving (Show) + +data DragonLairData a = MkDragonLair + { dragon :: Maybe DragonData, + treasureChest :: Maybe (TreasureChestData a) + } deriving (Show) + + + + {- =🛡= Typeclasses @@ -1068,6 +1088,28 @@ Implement instances of "Append" for the following types: class Append a where append :: a -> a -> a +data GoldData = MkGold + { totalGold :: Int + } deriving (Eq, Show) + +instance Append GoldData where + append :: GoldData -> GoldData -> GoldData + append loot1 loot2 = MkGold (totalGold loot1 + totalGold loot2) + +data List a + = Empty + | Cons a (List a) + deriving (Eq, Show) + +instance Append (List b) where + append :: List a -> List a -> List a + append list1 Empty = list1 + append Empty list1 = list1 + append (Cons valor1 Empty) (Cons valor2 Empty) = Cons valor1 (Cons valor2 Empty) + append (Cons valor1 lista1) (Cons valor2 Empty) = Cons valor1 (Cons valor2 lista1) + append (Cons valor1 lista1) (Cons valor2 lista2) = append (Cons valor1 (Cons valor2 lista1)) lista2 + + {- =🛡= Standard Typeclasses and Deriving From 3eb32196b804557d24f663b418b18805971a4952 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Sat, 7 Jan 2023 15:06:02 -0300 Subject: [PATCH 25/36] feat task 8 days of week --- src/Chapter3.hs | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/Chapter3.hs b/src/Chapter3.hs index 75c5f4db1..2bce7c6ef 100644 --- a/src/Chapter3.hs +++ b/src/Chapter3.hs @@ -1096,6 +1096,13 @@ instance Append GoldData where append :: GoldData -> GoldData -> GoldData append loot1 loot2 = MkGold (totalGold loot1 + totalGold loot2) +newtype Gold = Gold Int + deriving (Show) + +instance Append Gold where + append :: Gold -> Gold -> Gold + append (Gold a) (Gold b) = Gold (a + b) + data List a = Empty | Cons a (List a) @@ -1109,6 +1116,25 @@ instance Append (List b) where append (Cons valor1 lista1) (Cons valor2 Empty) = Cons valor1 (Cons valor2 lista1) append (Cons valor1 lista1) (Cons valor2 lista2) = append (Cons valor1 (Cons valor2 lista1)) lista2 +instance Append Int where + append :: Int -> Int -> Int + append a b = a + b + +instance (Append a) => Append [a] where + append :: [a] -> [a] -> [a] + append arr1 arr2 = arr1 ++ arr2 + +-- instance Append String where +-- append :: a -> a -> a +-- append arr1 arr2 = arr1 ++ arr2 + +instance (Append a) => Append (Maybe a) where + append :: Maybe a -> Maybe a -> Maybe a + append Nothing Nothing = Nothing + append container1 Nothing = container1 + append Nothing container1 = container1 + append (Just s1) (Just s2) = Just (append s1 s2) + {- @@ -1171,6 +1197,56 @@ implement the following functions: 🕯 HINT: to implement this task, derive some standard typeclasses -} + +data DiasDaSemana + = Segunda -- 0 + | Terca + | Quarta + | Quinta + | Sexta -- 4 + | Sabado + | Domingo + deriving (Show, Eq, Ord) + +isWeekend :: DiasDaSemana -> Bool +isWeekend a + | a == Sabado = True + | a == Domingo = True + | otherwise = False + +nextDay :: DiasDaSemana -> DiasDaSemana +nextDay Domingo = Segunda +nextDay a = toEnum ((fromEnum a) + 1) + +daysToParty :: DiasDaSemana -> Int +daysToParty Sexta = 0 +daysToParty Sabado = 2 + daysToParty Segunda +daysToParty Domingo = 1 + daysToParty Segunda +-- o /= Sexta é um lambda infix -- cria a lista de a até sexta, separa num array e conta qntos tem +daysToParty a = length $ takeWhile ( /= Sexta) [a .. Sexta] + +instance Enum DiasDaSemana where + toEnum :: Int -> DiasDaSemana + toEnum 0 = Segunda + toEnum 1 = Terca + toEnum 2 = Quarta + toEnum 3 = Quinta + toEnum 4 = Sexta + toEnum 5 = Sabado + toEnum 6 = Domingo + + fromEnum :: DiasDaSemana -> Int + fromEnum Segunda = 0 + fromEnum Terca = 1 + fromEnum Quarta = 2 + fromEnum Quinta = 3 + fromEnum Sexta = 4 + fromEnum Sabado = 5 + fromEnum Domingo = 6 + +daysToPartyInstance :: DiasDaSemana -> Int +daysToPartyInstance day = fromEnum (Sexta :: DiasDaSemana) - fromEnum day + {- =💣= Task 9* From 189f7d471aab7b9960460dc3206cf794bcad6023 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Mon, 9 Jan 2023 20:27:01 -0300 Subject: [PATCH 26/36] wip - work in progress charter 4 --- src/Chapter3.hs | 34 +++++++++++++++++++++++++++++++++- src/Chapter4.hs | 6 ++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/Chapter3.hs b/src/Chapter3.hs index 2bce7c6ef..9040ffd57 100644 --- a/src/Chapter3.hs +++ b/src/Chapter3.hs @@ -1281,6 +1281,38 @@ properties using typeclasses, but they are different data types in the end. Implement data types and typeclasses, describing such a battle between two contestants, and write a function that decides the outcome of a fight! -} +{- + +1) A knight can attack, drink a health potion, cast a spell to increase their defence. +while knights also have a defence. + +2) A monster can only attack or run away. Monsters have only health and attack + +3) They do their activities in turns, i.e. one fighter goes first, then +the other goes second, then the first again, and so on, until one of them wins. + +4) Both knight and monster have a sequence of actions they can do + +5) each fighter starts with some list of actions they can do + +6) The fight ends when the health of one fighter becomes zero or less. +-} + +data Actions = Attack | DrinkToCure | CastDef | RunAway + deriving (Show, Eq, Ord) + +data NewKnight = MkNewKnight + { newKHealth :: Int + , newKDefense :: Int + , newFAtions :: [Actions] + } deriving (Show) + +data NewMonster = MkNewMonster { newMoHealth :: Int, newMAtions :: [Actions] } + deriving (Show) + + +francisco = (MkNewKnight 10, 0, [CastDef, Attack, Attack, DrinkToCure]) +lizzard = (MkNewMonster 5, [Attack, Attack, Attack]) {- @@ -1292,4 +1324,4 @@ and summon @vrom911 for the review! =📜= Additional resources Deriving: https://kowainik.github.io/posts/deriving Extensions: https://kowainik.github.io/posts/extensions --} +-} \ No newline at end of file diff --git a/src/Chapter4.hs b/src/Chapter4.hs index e794a881d..aefd946aa 100644 --- a/src/Chapter4.hs +++ b/src/Chapter4.hs @@ -40,6 +40,7 @@ Perfect. Let's crush this! {-# LANGUAGE InstanceSigs #-} module Chapter4 where +import System.Win32 (xBUTTON1) {- | =🛡= Kinds @@ -267,6 +268,9 @@ instance Functor Maybe where @ -} +Qualquer função aplicada a x não faz sentido pois temos que acessar o que está dentro de x +Alem disso Functor Maybe já existe. + {- | =⚔️= Task 2 @@ -307,6 +311,8 @@ data List a = Empty | Cons a (List a) + fazer + {- | =🛡= Applicative From fd7d1adbebce399a1aa786da29d181b9cb03ed53 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Thu, 12 Jan 2023 15:49:37 +0000 Subject: [PATCH 27/36] Charter 3 complete --- src/Chapter3.hs | 66 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/src/Chapter3.hs b/src/Chapter3.hs index 9040ffd57..9625d0187 100644 --- a/src/Chapter3.hs +++ b/src/Chapter3.hs @@ -52,6 +52,7 @@ provide more top-level type signatures, especially when learning Haskell. {-# LANGUAGE InstanceSigs #-} module Chapter3 where +import Data.Either -- import LearnHaskell (TreasureChest(TreasureChest)) -- import Distribution.PackageDescription (Library) @@ -1301,18 +1302,73 @@ the other goes second, then the first again, and so on, until one of them wins. data Actions = Attack | DrinkToCure | CastDef | RunAway deriving (Show, Eq, Ord) +data ActionChange = Hero | Antagonist + deriving (Show, Eq, Ord) + data NewKnight = MkNewKnight { newKHealth :: Int , newKDefense :: Int - , newFAtions :: [Actions] } deriving (Show) -data NewMonster = MkNewMonster { newMoHealth :: Int, newMAtions :: [Actions] } +data NewMonster = MkNewMonster { newMoHealth :: Int } deriving (Show) - -francisco = (MkNewKnight 10, 0, [CastDef, Attack, Attack, DrinkToCure]) -lizzard = (MkNewMonster 5, [Attack, Attack, Attack]) +class Luta a where + toAttack :: a -> a + +instance Luta NewMonster where + toAttack :: NewMonster -> NewMonster + toAttack (MkNewMonster mhealth) = MkNewMonster (mhealth - 1) + +instance Luta NewKnight where + toAttack :: NewKnight -> NewKnight + toAttack (MkNewKnight khealth kdef) = if kdef > 0 + then MkNewKnight (khealth) (kdef -1) + else MkNewKnight (khealth - 1) kdef + +-- todo retornar o either auqi nao ficou legal +parseActionKnight :: NewKnight -> Actions -> NewKnight +parseActionKnight (MkNewKnight khealth kdef) action + | action == DrinkToCure = (MkNewKnight (khealth + 1) kdef) + | action == CastDef = (MkNewKnight khealth (kdef + 1)) + | otherwise = (MkNewKnight khealth kdef) + +parseActionMonster :: NewMonster -> Actions -> NewMonster +parseActionMonster (MkNewMonster khealth) action + | action == RunAway = (MkNewMonster 0) + | otherwise = (MkNewMonster khealth) + +rotate :: Int -> [a] -> [a] +rotate _ [] = [] +rotate n arr = drop n $ take ((length arr) + n) $ cycle arr + + +francisco = (MkNewKnight 13 2) +lizzard = (MkNewMonster 5) + +tank = (MkNewKnight 100 2) +stronger = (MkNewMonster 13) + +actionOrder = [Hero, Antagonist] +kaction = [Attack, DrinkToCure, CastDef] +maction = [Attack, Attack, Attack, Attack, Attack, Attack, Attack, Attack, Attack, Attack, RunAway] + +figthToDeath :: NewKnight -> NewMonster -> [Actions] -> [Actions] -> [ActionChange] -> String +figthToDeath (MkNewKnight khealth kdef) (MkNewMonster mhealth) arrK arrM order + | head order == Hero = if (head arrK) == Attack then (if mhealth > 0 + then figthToDeath (MkNewKnight khealth kdef) (toAttack (MkNewMonster mhealth)) (rotate 1 arrK) (rotate 1 arrM) (rotate 1 order) + else "!!Hero wins!! Hero life:" ++ (show khealth) ++ " - Monster life: " ++ (show mhealth) ) + else figthToDeath (MkNewKnight khealth kdef) (MkNewMonster mhealth) (rotate 1 arrK) (rotate 1 arrM) (rotate 1 order) + | otherwise = if (head arrM) == Attack then (if khealth > 0 + then figthToDeath (toAttack (MkNewKnight khealth kdef)) (MkNewMonster mhealth) (rotate 1 arrK) (rotate 1 arrM) (rotate 1 order) + else "Monster wins!! Hero life:" ++ (show khealth) ++ " - Monster life: " ++ (show mhealth) ) + else figthToDeath (MkNewKnight khealth kdef) (MkNewMonster mhealth) (rotate 1 arrK) (rotate 1 arrM) (rotate 1 order) + +-- to execute +-- figthToDeath francisco lizzard kaction maction actionOrder +-- figthToDeath tank stronger kaction maction actionOrder + +-- WOW - thas hard!! {- From f44746ac9e33afbb1a84fe6eade7edcadcb1e308 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Thu, 12 Jan 2023 16:24:33 +0000 Subject: [PATCH 28/36] feat: Chapter 4 - Task 3 - complete --- src/Chapter4.hs | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/Chapter4.hs b/src/Chapter4.hs index aefd946aa..e3f7ce508 100644 --- a/src/Chapter4.hs +++ b/src/Chapter4.hs @@ -40,7 +40,7 @@ Perfect. Let's crush this! {-# LANGUAGE InstanceSigs #-} module Chapter4 where -import System.Win32 (xBUTTON1) +-- import System.Win32 (xBUTTON1) {- | =🛡= Kinds @@ -268,8 +268,21 @@ instance Functor Maybe where @ -} -Qualquer função aplicada a x não faz sentido pois temos que acessar o que está dentro de x -Alem disso Functor Maybe já existe. +{- + -- response: + Any function applied to x doesn't make sense as we have to access what's inside x (a) and transform to b (a -> b) + And Functor Maybe already exists. +-} + +-- data Maybe2 e +-- = Just2 e +-- | Nothing2 + +-- instance Functor Maybe2 where +-- fmap :: (a -> b) -> Maybe2 a -> Maybe2 b +-- fmap f (Just2 a) = Just2 (f a) +-- fmap _ x = x + {- | =⚔️= Task 2 @@ -294,10 +307,9 @@ we can reuse already known concepts (e.g. partial application) from values and apply them to the type level? -} instance Functor (Secret e) where - fmap :: (a -> b) -> Secret e a -> Secret e b - fmap _ (Trap e) = Trap e - fmap f (Reward a) = Reward (f a) --- fmap (++"teste2") a + fmap :: (a -> b) -> Secret e a -> Secret e b + fmap _ (Trap e) = Trap e + fmap f (Reward a) = Reward (f a) {- | =⚔️= Task 3 @@ -310,8 +322,20 @@ typeclasses for standard data types. data List a = Empty | Cons a (List a) + deriving (Show) + +instance Functor List where + fmap :: (a -> b) -> List a -> List b + fmap _ Empty = Empty + fmap f (Cons a (blist)) = Cons (f a) (fmap f blist) + + +list1 = Empty +list2 = Cons 10 (Cons 20 Empty) +list3 = Cons 10 (Cons 20 (Cons 30 Empty)) - fazer +-- fmap (+10) list3 +-- Cons 20 (Cons 30 (Cons 40 Empty)) {- | =🛡= Applicative From 690374f1c957dc9a9e40a927df529ae5441945b3 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Mon, 16 Jan 2023 14:29:19 +0000 Subject: [PATCH 29/36] feat: Chapter 4 - task 4 done! --- src/Chapter4.hs | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/Chapter4.hs b/src/Chapter4.hs index e3f7ce508..55ff9b7b7 100644 --- a/src/Chapter4.hs +++ b/src/Chapter4.hs @@ -500,12 +500,29 @@ Applicatives can be found in many applications: Implement the Applicative instance for our 'Secret' data type from before. -} --- instance Applicative (Secret e) where --- pure :: a -> Secret e a --- pure = error "pure Secret: Not implemented!" +instance Applicative (Secret e) where + pure :: a -> Secret e a + pure = Reward + (<*>) :: Secret e (a -> b) -> Secret e a -> Secret e b + (Trap a) <*> _ = Trap a + _ <*> (Trap a) = Trap a + (Reward f) <*> i = fmap f i --- (<*>) :: Secret e (a -> b) -> Secret e a -> Secret e b --- (<*>) = error "(<*>) Secret: Not implemented!" +-- tests +secret1 = Trap "you die" +secret2 = Reward 10 +secret3 = Reward 20 + +-- die +-- fmap (+10) secret1 + +-- 50 +-- fmap (+40) secret2 + +-- 20 +-- Reward (+10) <*> Reward 10 + +-- hell yeah!! {- | =⚔️= Task 5 From 78e2e12b420387672c39ae4e5b26d988d6c54e5b Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Mon, 16 Jan 2023 20:49:55 +0000 Subject: [PATCH 30/36] feat: Chapter4 - task 5 --- src/Chapter4.hs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/Chapter4.hs b/src/Chapter4.hs index 55ff9b7b7..eb602cca9 100644 --- a/src/Chapter4.hs +++ b/src/Chapter4.hs @@ -536,6 +536,27 @@ Implement the 'Applicative' instance for our 'List' type. type. -} +list4 = Cons (+5) Empty +list5 = Cons (+5) (Cons (+6) Empty) +list6 = Cons (+1) (Cons (+2) (Cons (+3) Empty)) +list7 = Cons 1 (Cons 2 (Cons 3 Empty)) + +combineList :: List a -> List a -> List a +combineList Empty l1 = l1 +combineList l1 Empty = l1 +combineList (Cons x xs) l2 = Cons x (combineList xs l2) + +instance Applicative List where + pure :: a -> List a + pure a = Cons a Empty + (<*>) :: List (a -> b) -> List a -> List b + Empty <*> _ = Empty + _ <*> Empty = Empty + -- (Cons f l) <*> i = fmap f i + -- (Cons f (Cons l emp)) <*> i = fmap l i + (Cons f emp) <*> i = combineList (fmap f i) (emp <*> i) + +-- list6 <*> list7 {- | =🛡= Monad From c1c04bd7ecb7173aa7cb49bdd35990b664abc44a Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Wed, 18 Jan 2023 10:49:02 +0000 Subject: [PATCH 31/36] feat: Chapter4 - task 6 and 7 done --- src/Chapter4.hs | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/Chapter4.hs b/src/Chapter4.hs index eb602cca9..6eb108146 100644 --- a/src/Chapter4.hs +++ b/src/Chapter4.hs @@ -311,6 +311,20 @@ instance Functor (Secret e) where fmap _ (Trap e) = Trap e fmap f (Reward a) = Reward (f a) +-- example +addOneGold :: (Integral a, Num a) => (Secret e a) -> (Secret e a) +addOneGold (Trap e) = Trap e +addOneGold (Reward a) = Reward (a + 1) + +addToChest :: (Integral a, Num a, Num e) => a -> (Secret e a) +addToChest a + | a == 0 = (Trap 0) + | otherwise = Reward a + +-- addOneGold (Reward 1) +-- addOneGold $ Reward 1 +-- fmap (addToChest) (Reward 1) + {- | =⚔️= Task 3 @@ -670,6 +684,25 @@ Implement the 'Monad' instance for our 'Secret' type. -- (>>=) :: Secret e a -> (a -> Secret e b) -> Secret e b -- (>>=) = error "bind Secret: Not implemented!" +instance Monad (Secret e) where + (>>=) :: Secret e a -> (a -> Secret e b) -> Secret e b + (Trap c) >>= f = Trap c + (Reward c) >>= f = f c + +test :: Int -> Secret Int Int +test n + | n == 1 = Trap 1 + | otherwise = Reward (n + 1) + + + +-- test +-- Trap 11 >>= test +-- Reward 11 >>= test + + + + {- | =⚔️= Task 7 @@ -679,6 +712,24 @@ Implement the 'Monad' instance for our lists. maybe a few) to flatten lists of lists to a single list. -} +flattenList :: List (List a) -> List a +flattenList Empty = Empty +flattenList (Cons x xs) = combineList x (flattenList xs) + +instance Monad List where + (>>=) :: List a -> (a -> List b) -> List b + list1 >>= func = flattenList (fmap func list1) + +addOneOnList :: (Integral a, Num a) => a -> List a +addOneOnList n = Cons (n + 1) Empty + +listC = Cons list2 Empty + +-- exemplo de uso +-- list2 >>= addOneOnList +-- list3 >>= addOneOnList +-- list3 >>= addOneOnList >>= addOneOnList + {- | =💣= Task 8*: Before the Final Boss From 178302cf793b4faa6dea2b7a13679874d20050ed Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Thu, 19 Jan 2023 10:35:42 +0000 Subject: [PATCH 32/36] feat: Chapter 4 - task 8 --- src/Chapter4.hs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Chapter4.hs b/src/Chapter4.hs index 6eb108146..c32d19085 100644 --- a/src/Chapter4.hs +++ b/src/Chapter4.hs @@ -748,7 +748,28 @@ Can you implement a monad version of AND, polymorphic over any monad? 🕯 HINT: Use "(>>=)", "pure" and anonymous function -} andM :: (Monad m) => m Bool -> m Bool -> m Bool -andM = error "andM: Not implemented!" +andM contextB1 contextB2 = contextB1 >>= \f -> if f then contextB2 else pure False + +tJust1 = Just True +tJust2 = Just False +tJust3 = Nothing +tEither1 = Left True +tEither2 = Left False +tEither3 = Right True + +-- Nothing and _ = False +-- _ and Nothing = False +-- Just True and Just True = True +-- Just True and Just False = False +-- Just False and Just False = False +-- Just False and Just True = False + +-- andM tJust1 tJust1 = True +-- andM tJust1 tJust2 = False +-- andM TJust2 tJust1 = False + +half2 :: (Monad m) => m Integer -> m Integer +half2 monadInt = monadInt >>= \x -> if even x then pure (div x 2) else pure 0 {- | =🐉= Task 9*: Final Dungeon Boss From ae2724930e894449e0febe3847b9de769abd878a Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Thu, 19 Jan 2023 10:47:25 +0000 Subject: [PATCH 33/36] wip: final boss chapter 4 --- src/Chapter4.hs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Chapter4.hs b/src/Chapter4.hs index c32d19085..cf8eadc17 100644 --- a/src/Chapter4.hs +++ b/src/Chapter4.hs @@ -806,12 +806,32 @@ Specifically, ❃ Implement a polymorphic binary tree type that can store any elements inside its nodes + ❃ Implement the Functor instance for Tree + ❃ Implement the reverseTree function that reverses the tree and each subtree of a tree + ❃ Implement the function to convert Tree to list -} +data MyBtree a + = BEmpty + | MkMyBTree (MyBtree a) a (MyBtree a) + deriving (Show) + +tree1 = BEmpty +tree2 = MkMyBTree (BEmpty) 10 (BEmpty) +tree3 = MkMyBTree (MkMyBTree (BEmpty) 20 (BEmpty)) 10 (MkMyBTree (BEmpty) 20 (BEmpty)) +tree4 = MkMyBTree (MkMyBTree ((MkMyBTree (BEmpty) 30 (BEmpty))) 20 ((MkMyBTree (BEmpty) 30 (BEmpty)))) 10 (MkMyBTree ((MkMyBTree (BEmpty) 30 (BEmpty))) 20 ((MkMyBTree (BEmpty) 30 (BEmpty)))) +treeString = MkMyBTree (MkMyBTree (BEmpty) "Adriano" (BEmpty)) "Joao" (MkMyBTree (BEmpty) "André" (BEmpty)) + +instance Functor MyBtree where + fmap :: (a -> b) -> MyBtree a -> MyBtree b + fmap _ BEmpty = BEmpty + fmap f (MkMyBTree (ltree) a (rtree)) = MkMyBTree (fmap f rtree) (f a) (fmap f rtree) + +-- fmap (+10) tree2 {- You did it! Now it is time to open pull request with your changes From 461855a58c8822ace83fa938619742ae8c6c7d02 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Thu, 19 Jan 2023 11:12:48 +0000 Subject: [PATCH 34/36] wip: final boss chapter 4 --- src/Chapter4.hs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Chapter4.hs b/src/Chapter4.hs index cf8eadc17..60ddc04aa 100644 --- a/src/Chapter4.hs +++ b/src/Chapter4.hs @@ -824,6 +824,7 @@ tree1 = BEmpty tree2 = MkMyBTree (BEmpty) 10 (BEmpty) tree3 = MkMyBTree (MkMyBTree (BEmpty) 20 (BEmpty)) 10 (MkMyBTree (BEmpty) 20 (BEmpty)) tree4 = MkMyBTree (MkMyBTree ((MkMyBTree (BEmpty) 30 (BEmpty))) 20 ((MkMyBTree (BEmpty) 30 (BEmpty)))) 10 (MkMyBTree ((MkMyBTree (BEmpty) 30 (BEmpty))) 20 ((MkMyBTree (BEmpty) 30 (BEmpty)))) +tree5 = MkMyBTree (MkMyBTree ((MkMyBTree (BEmpty) 4 (BEmpty))) 6 ((MkMyBTree (BEmpty) 3 (BEmpty)))) 7 (MkMyBTree ((MkMyBTree (BEmpty) 2 (BEmpty))) 5 ((MkMyBTree (BEmpty) 1 (BEmpty)))) treeString = MkMyBTree (MkMyBTree (BEmpty) "Adriano" (BEmpty)) "Joao" (MkMyBTree (BEmpty) "André" (BEmpty)) instance Functor MyBtree where @@ -833,6 +834,14 @@ instance Functor MyBtree where -- fmap (+10) tree2 +convertToArr :: MyBtree a -> [a] +convertToArr BEmpty = [] +convertToArr (MkMyBTree (ltree) x (rtree)) = [x] ++ convertToArr ltree ++ convertToArr rtree + +makeListFromTree :: MyBtree a -> List a +makeListFromTree BEmpty = Empty +makeListFromTree (MkMyBTree (ltree) x (rtree)) = combineList (Cons x (makeListFromTree ltree)) (makeListFromTree rtree) + {- You did it! Now it is time to open pull request with your changes and summon @vrom911 for the review! From 5de47683f661724821899906fc2905894c5c856a Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Fri, 20 Jan 2023 11:19:12 +0000 Subject: [PATCH 35/36] feat: Chapter 4 completed --- src/Chapter4.hs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Chapter4.hs b/src/Chapter4.hs index 60ddc04aa..7484a2b7a 100644 --- a/src/Chapter4.hs +++ b/src/Chapter4.hs @@ -834,14 +834,25 @@ instance Functor MyBtree where -- fmap (+10) tree2 +reverseMyBTree :: MyBtree a -> MyBtree a +reverseMyBTree BEmpty = BEmpty +reverseMyBTree (MkMyBTree ltree x rtree) = MkMyBTree (reverseMyBTree rtree) x (reverseMyBTree ltree) + convertToArr :: MyBtree a -> [a] convertToArr BEmpty = [] convertToArr (MkMyBTree (ltree) x (rtree)) = [x] ++ convertToArr ltree ++ convertToArr rtree +-- convertToArr tree4 + makeListFromTree :: MyBtree a -> List a makeListFromTree BEmpty = Empty makeListFromTree (MkMyBTree (ltree) x (rtree)) = combineList (Cons x (makeListFromTree ltree)) (makeListFromTree rtree) + +-- makeListFromTree tree4 + +{-- huuuu ulll - it finish!!! } + {- You did it! Now it is time to open pull request with your changes and summon @vrom911 for the review! From 515ae94304116ba6c3866f0911018766c2c86326 Mon Sep 17 00:00:00 2001 From: Adriano Waltrick Date: Fri, 20 Jan 2023 11:35:27 +0000 Subject: [PATCH 36/36] feat: Chapter 4 completed --- src/Chapter4.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Chapter4.hs b/src/Chapter4.hs index 7484a2b7a..7d26c543b 100644 --- a/src/Chapter4.hs +++ b/src/Chapter4.hs @@ -851,7 +851,7 @@ makeListFromTree (MkMyBTree (ltree) x (rtree)) = combineList (Cons x (makeListFr -- makeListFromTree tree4 -{-- huuuu ulll - it finish!!! } +{-- huuuu ulll - it finish!!! -} {- You did it! Now it is time to open pull request with your changes