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/Chapter1.hs b/src/Chapter1.hs
index 406deeaca..2a01629e0 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
-<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.
@@ -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
@@ -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)
 
 
@@ -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
@@ -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 (abs 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,13 @@ 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 && 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 +574,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
 
 
 {- |
@@ -632,8 +645,21 @@ 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 (abs x) 10
+
+        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*
@@ -653,7 +679,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 abs n < 10
+    then abs n
+    else firstDigit (abs n `div` 10)
 
 
 {-
diff --git a/src/Chapter2.hs b/src/Chapter2.hs
index b98ceaf7d..0d0438a68 100644
--- a/src/Chapter2.hs
+++ b/src/Chapter2.hs
@@ -136,43 +136,44 @@ 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:
 >>> :t take
-
+take :: Int -> [a] -> [a]
 
 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
 
 -}
 
@@ -186,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
@@ -336,7 +348,12 @@ from it!
 ghci> :l src/Chapter2.hs
 -}
 subList :: Int -> Int -> [a] -> [a]
-subList = error "subList: Not implemented!"
+subList _ _ [] = []
+subList 0 0 b = take 1 b
+subList _ 0 _ = []
+subList x y b = if x >= 0
+  then take (y - x + 1) $ drop x b
+  else []
 
 {- |
 =βš”οΈ= Task 4
@@ -349,7 +366,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
 
 
 {- |
@@ -501,7 +521,11 @@ True
 >>> isThird42 [42, 42, 0, 42]
 False
 -}
-isThird42 = error "isThird42: Not implemented!"
+isThird42 :: (Eq a, Num a) => [a] -> Bool
+isThird42 [] = False
+isThird42 [_] = False
+isThird42 [_, _] = False
+isThird42 ( _ : _ : x : _ ) = x == 42
 
 
 {- |
@@ -606,7 +630,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
 
 
 {- |
@@ -621,7 +646,20 @@ 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
+takeEven :: [a] -> [a]
+takeEven [] = []
+takeEven [x] = [x]
+takeEven ( x : _ : xs ) = [x] ++ takeEven xs
+
 
 {- |
 =πŸ›‘= Higher-order functions
@@ -727,8 +765,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
@@ -741,8 +784,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
@@ -781,13 +828,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
@@ -842,7 +891,9 @@ list.
 
 πŸ•― HINT: Use the 'cycle' function
 -}
-rotate = error "rotate: Not implemented!"
+rotate :: Int -> [a] -> [a]
+rotate _ [] = []
+rotate n arr = drop n $ take ((length arr) + n) $ cycle arr
 
 {- |
 =πŸ’£= Task 12*
@@ -858,9 +909,17 @@ and reverses it.
   function, but in this task, you need to implement it manually. No
   cheating!
 -}
-rewind = error "rewind: Not Implemented!"
+rewind' :: [a] -> [a]
+rewind' [] = []
+rewind' (x:xs) = (rewind' xs) ++ [x]
 
 
+rewind :: [a] -> [a]
+rewind [] = []
+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
 and summon @vrom911 for the review!
diff --git a/src/Chapter3.hs b/src/Chapter3.hs
index 061811064..9625d0187 100644
--- a/src/Chapter3.hs
+++ b/src/Chapter3.hs
@@ -52,6 +52,9 @@ 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)
 
 {-
 =πŸ›‘= Types in Haskell
@@ -344,6 +347,28 @@ 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
+    }
+
+livrinho = MkBook { bookName = "meu livro", bookCover = "wow", bookAuthor = "Adriano Waltrick", bookLanguage = "Portuguese", bookPages = 100, bookRating = 10}
+-}
+
 {- |
 =βš”οΈ= Task 2
 
@@ -376,6 +401,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
 
@@ -462,6 +521,15 @@ 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
+    | BolachaRecheada
+    | Biscoito
+    | Brigadeiro
+
 {- |
 =βš”οΈ= Task 4
 
@@ -482,6 +550,96 @@ 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 (Eq, 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 PeopleInsideHouse
+    = None
+    | One
+    | Two
+    | Three
+    | Four
+    deriving (Show, Eq, Ord, Enum)
+
+data House = MkHouse
+    { people :: PeopleInsideHouse
+    } deriving (Show)
+
+data City = MkCity
+    { castle :: Maybe Castle
+    , wall :: Maybe Wall
+    , churchOrLibrary :: Maybe ChurchOrLibrary
+    , houses :: [House]
+    } deriving (Show)
+
+igreja1 :: ChurchOrLibrary
+igreja1 = Church (MkChurch "Igreja1")
+
+buildCastle :: City -> String -> City
+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 _ _ _ []) = 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 (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 countPeoplesArray xhouses < 10 then Nothing
+    else Just (MkCity xcastle (Just (MkWall (nwalls + iwall))) xchurchOrLibrary xhouses)
+
 {-
 =πŸ›‘= Newtypes
 
@@ -570,21 +728,24 @@ 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
 
 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
 hitPlayer player1 player2 =
     let damage = calculatePlayerDamage
-            (playerAttack player2)
-            (playerStrength player2)
+            (MkPlayerAttack (playerAttack player2))
+            (MkPlayerStrength (playerStrength player2))
         defense = calculatePlayerDefense
             (playerArmor player1)
             (playerDexterity player1)
@@ -755,6 +916,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
 
@@ -912,6 +1089,54 @@ 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)
+
+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)
+    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
+
+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)
+
+
 
 {-
 =πŸ›‘= Standard Typeclasses and Deriving
@@ -973,6 +1198,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*
 
@@ -1007,6 +1282,93 @@ 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 ActionChange = Hero | Antagonist
+    deriving (Show, Eq, Ord)
+
+data NewKnight = MkNewKnight
+    { newKHealth  :: Int
+    , newKDefense :: Int
+    } deriving (Show)
+
+data NewMonster = MkNewMonster { newMoHealth :: Int }
+    deriving (Show)
+
+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!!
 
 
 {-
@@ -1018,4 +1380,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 caec5a95d..7d26c543b 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,22 @@ instance Functor Maybe where
 @
 -}
 
+{-
+  -- 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
 
@@ -281,7 +298,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
@@ -292,7 +308,22 @@ 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 _ (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
@@ -305,6 +336,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))
+
+-- fmap (+10) list3
+-- Cons 20 (Cons 30 (Cons 40 Empty))
 
 {- |
 =πŸ›‘= Applicative
@@ -471,10 +516,27 @@ 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!"
-
+    pure = Reward
     (<*>) :: Secret e (a -> b) -> Secret e a -> Secret e b
-    (<*>) = error "(<*>) Secret: Not implemented!"
+    (Trap a) <*> _ = Trap a
+    _ <*> (Trap a) = Trap a
+    (Reward f) <*> i = fmap f i
+
+-- 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
@@ -488,6 +550,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
@@ -597,9 +680,28 @@ 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!"
+    (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
@@ -610,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
@@ -628,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
@@ -665,12 +806,52 @@ 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))))
+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
+    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
+
+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