Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

completed Chapter 3 #543

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 138 additions & 12 deletions src/Chapter3.hs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,13 @@ Define the Book product data type. You can take inspiration from our description
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
, bookAuthor :: String
, bookIsbn :: Int
, bookPublisher :: String
}

{- |
=⚔️= Task 2
Expand Down Expand Up @@ -375,6 +382,42 @@ after the fight. The battle has the following possible outcomes:
♫ NOTE: In this task, you need to implement only a single round of the fight.

-}
data Knight = MkKnight{
knightName :: String
, knightHealth :: Int
, knightAttack :: Int
, knightGold :: Int
}deriving(Show)

data Monster = MkMonster{
monsterName :: String,
monsterHealth :: Int,
monsterAttack :: Int,
monsterGold :: Int
}deriving(Show)

jonSnow :: Knight
jonSnow = MkKnight{
knightName = "Jon Snow"
, knightAttack = 10
, knightHealth = 100
, knightGold = 20
}

nightKing :: Monster
nightKing = MkMonster{
monsterName = "Night King",
monsterAttack = 20,
monsterHealth = 100,
monsterGold = 20
}

fight :: Knight -> Monster -> Int
fight k m
| monsterHealth m < knightAttack k = (knightGold k + monsterGold m)
| knightHealth k < monsterAttack m = -1
| otherwise = knightGold k


{- |
=🛡= Sum types
Expand Down Expand Up @@ -461,6 +504,7 @@ and provide more flexibility when working with data types.
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 Meal = Breakfast | Brunch | Lunch | Linner | Dinner

{- |
=⚔️= Task 4
Expand All @@ -481,6 +525,37 @@ After defining the city, implement the following functions:
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.
-}
data City = MkCity{
cityCastle :: Castle,
cityPublic :: Public,
cityHouses :: [House]
}
data Castle = None | WithoutWall String | WithWall String
data Public = Church | Library
data House = One | Two | Three | Four

buildCastle :: String -> City -> City
buildCastle castleName city = case cityCastle city of
WithWall _ -> city {cityCastle = WithWall castleName}
_ -> city { cityCastle = WithoutWall castleName}

buildHouse :: House -> City ->City
buildHouse house city = city { cityHouses = house : cityHouses city}

countHouse :: House -> Int
countHouse house = case house of
One -> 1
Two -> 2
Three -> 3
Four -> 4

buildWalls :: City -> City
buildWalls city = case cityCastle city of
WithoutWall castleName -> if sum(map countHouse (cityHouses city))>=10 then city {cityCastle = WithWall castleName} else city
_ -> city




{-
=🛡= Newtypes
Expand Down Expand Up @@ -562,22 +637,32 @@ introducing extra newtypes.
🕯 HINT: if you complete this task properly, you don't need to change the
implementation of the "hitPlayer" function at all!
-}
newtype Attack = MkAttack Int
newtype Strength = MkStrength Int
newtype Dexterity = MkDexterity Int
newtype Armor = MkArmor Int
newtype Health = MkHealth Int
newtype Defense = MkDefense Int
newtype Damage = MkDamage Int

data Player = Player
{ playerHealth :: Int
, playerArmor :: Int
, playerAttack :: Int
, playerDexterity :: Int
, playerStrength :: Int
{ playerHealth :: Health
, playerArmor :: Armor
, playerAttack :: Attack
, playerDexterity :: Dexterity
, playerStrength :: Strength
}

calculatePlayerDamage :: Int -> Int -> Int
calculatePlayerDamage attack strength = attack + strength

calculatePlayerDefense :: Int -> Int -> Int
calculatePlayerDefense armor dexterity = armor * dexterity

calculatePlayerHit :: Int -> Int -> Int -> Int
calculatePlayerHit damage defense health = health + defense - damage
calculatePlayerDamage :: Attack -> Strength -> Damage
calculatePlayerDamage (MkAttack attack) (MkStrength strength) = MkDamage (attack + strength)

calculatePlayerDefense :: Armor -> Dexterity -> Defense
calculatePlayerDefense (MkArmor armor) (MkDexterity dexterity) = MkDefense (armor * dexterity)

calculatePlayerHit :: Damage -> Defense -> Health -> Health
calculatePlayerHit (MkDamage damage) (MkDefense defense) (MkHealth health) = MkHealth (health + defense - damage)

-- The second player hits first player and the new first player is returned
hitPlayer :: Player -> Player -> Player
Expand Down Expand Up @@ -754,6 +839,14 @@ parametrise data types in places where values can be of any general type.
🕯 HINT: 'Maybe' that some standard types we mentioned above are useful for
maybe-treasure ;)
-}
data DragonLair treasure power=DragonLair{
dragonLairChest :: Maybe (TreasureChest treasure),
dragonLairPower :: power
}
data TreasureChest x = TreasureChest
{ treasureChestGold :: Int
, treasureChestLoot :: x
}

{-
=🛡= Typeclasses
Expand Down Expand Up @@ -909,8 +1002,21 @@ Implement instances of "Append" for the following types:
✧ *(Challenge): "Maybe" where append is appending of values inside "Just" constructors

-}

newtype Gold = Gold Int
class Append a where
append :: a -> a -> a
instance Append Gold where
append :: Gold -> Gold -> Gold
append (Gold g1) (Gold g2) = Gold (g1 + g2)
instance Append [a] where
append :: [a] -> [a] -> [a]
append l1 l2 = l1 ++ l2
instance (Append a) => Append (Maybe a) where
append :: Maybe a -> Maybe a -> Maybe a
append (Just x) (Just y) = Just(append x y)
append Nothing x = x
append x Nothing = x


{-
Expand Down Expand Up @@ -972,7 +1078,27 @@ implement the following functions:

🕯 HINT: to implement this task, derive some standard typeclasses
-}

data Day =
Mon
| Tue
| Wed
| Thu
| Fri
| Sat
| Sun
deriving (Show,Enum,Eq,Bounded)

isWeekend :: Day -> Bool
isWeekend day
| day == Sat = True
| day == Sun = True
| otherwise = False
nextDay :: Day -> Day
nextDay day
| day == maxBound = minBound
| otherwise = succ day
daysToParty :: Day -> Int
daysToParty day = mod (fromEnum Fri - fromEnum day) 7
{-
=💣= Task 9*

Expand Down