Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
pp:2023:haskell:l09 [2023/04/30 11:44] bogdan.deac |
pp:2023:haskell:l09 [2023/05/02 22:15] (current) bogdan.deac |
||
---|---|---|---|
Line 45: | Line 45: | ||
age myDog --5 | age myDog --5 | ||
</code> | </code> | ||
+ | |||
+ | |||
+ | Typeclasses are an important concept in haskell. They are very similar in concept to Java interfaces (we implement certain behaviours through them). For example, we might want to convert an entity to a string to print it. This could be done by implementing the Show class. Take a look at its [[https://hackage.haskell.org/package/base-4.18.0.0/docs/src/GHC.Show.html#Show | implementation]]. Notice the ''{-# MINIMAL showsPrec | show #-}''. That tells us that it's enough to implement one of those functions to have a complete implementation. Let's implement show for ''Maybe a'' | ||
+ | |||
+ | <code haskell> | ||
+ | -- The syntax "Show a =>" is called a constraint. This tells us that a also needs to be an instance of Show. Why do we need it here? | ||
+ | instance Show a => Show (Maybe a) where | ||
+ | show Nothing = "Nothing" | ||
+ | show (Just x) = "Just " ++ show x | ||
+ | </code> | ||
+ | |||
+ | In summary, typeclasses allow us to abstract certain behaviours. Some important ones we'll use in this lab are ''Eq''(to specifiy whether 2 things are equal or different) or ''Ord'', to be able to compare type instances. | ||
After the lab, you can take a look at some more cool stuff related to data types in haskell and functional types in general \\ | After the lab, you can take a look at some more cool stuff related to data types in haskell and functional types in general \\ | ||
Line 52: | Line 64: | ||
===== 9.1. Chess Basics ===== | ===== 9.1. Chess Basics ===== | ||
- | **9.1.1** Let's implement a ''ChessResult'' data type. In chess, a game result can be either a Win, a Draw or a Loss. Make sure to add ''deriving Show''. | + | **9.1.1** Let's implement a ''ChessResult'' data type. In chess, a game result can be either a Win, a Draw or a Loss. |
+ | <code haskell> | ||
+ | data ChessResult = ??? | ||
+ | </code> | ||
+ | |||
+ | **9.1.2** We want to be able to show a ''ChessResult''. For this, we could do ''deriving Show'' to let GHC derive the implementation, but let's do it ourselves. | ||
<code haskell> | <code haskell> | ||
- | data ChessResult = ??? deriving Show | + | instance Show ChessResult where |
+ | ??? | ||
</code> | </code> | ||
- | **9.1.2** In chess, your performance is rated based on a point system. A win is equivalent to a point, a draw is 0.5 points and a loss is 0 points | + | **9.1.3** In chess, your performance is rated based on a point system. A win is equivalent to a point, a draw is 0.5 points and a loss is 0 points |
<code haskell> | <code haskell> | ||
points :: ChessResult -> Float | points :: ChessResult -> Float | ||
Line 63: | Line 81: | ||
</code> | </code> | ||
- | **9.1.3** We want to find out the number of point a player earns after playing multiple games. Try to implement this as a closure. | + | **9.1.4** We want to find out the number of point a player earns after playing multiple games. Try to implement this as a closure. |
<code haskell> | <code haskell> | ||
score :: [ChessResult] -> Float | score :: [ChessResult] -> Float | ||
Line 69: | Line 87: | ||
</code> | </code> | ||
- | **9.1.4** Now that we can measure a player's score, we want to establish a ranking. Return the descending list of scores. Hint: ''sort'' | + | **9.1.5** Now that we can measure a player's score, we want to establish a ranking. Return the descending list of scores. Hint: ''sort'' |
<code haskell> | <code haskell> | ||
ranking :: [[ChessResult]] -> [Float] | ranking :: [[ChessResult]] -> [Float] | ||
Line 75: | Line 93: | ||
</code> | </code> | ||
- | **9.1.5** Each tournament also offers a cash prize, based on player performance. Compute the earnings for each player. The formula we'll use is ''player_earnings = player points * prize money / total points'' | + | **9.1.6** Each tournament also offers a cash prize, based on player performance. Compute the earnings for each player. The formula we'll use is ''player_earnings = player points * prize money / total points'' |
<code haskell> | <code haskell> | ||
earnings :: [[ChessResult]] -> Float ->[Float] | earnings :: [[ChessResult]] -> Float ->[Float] | ||
Line 86: | Line 104: | ||
We also want to model a chess tournament. We'll represent it as a binary tree. | We also want to model a chess tournament. We'll represent it as a binary tree. | ||
<code Haskell> | <code Haskell> | ||
- | data player = Player { ??? } | + | data Player = Player { ??? } |
data Tree a = ??? deriving Show | data Tree a = ??? deriving Show | ||
type Tournament = Tree Player | type Tournament = Tree Player | ||
Line 145: | Line 163: | ||
</code> | </code> | ||
- | **9.2.8** Carolina wants to see how her beloved Romeo did in his first tournament. However, he sometimes goes to the 'chess' club instead of playing, so he may have not been present at all. Implement the function ''findPlayerByName'', to find a player's result in a tournament(1 if he is the winner, 2 if he reached semifinals, 3 for quarterfinals etc) | + | **9.2.8** Carolina wants to see how her beloved Romeo did. However, he sometimes goes to the 'chess' club instead of playing, so he may have not been present at all. Implement the function ''findPlayerScoreByName'', which returns ''Just score'' if he was there or ''Nothing'' if he wasn't |
<code haskell> | <code haskell> | ||
- | findPlayerByName :: String -> Tournament -> Maybe Int | + | findPlayerScoreByName :: String -> Tournament -> Maybe Float |
- | findPlayerByName = ??? | + | findPlayerScoreByName = ??? |
</code> | </code> | ||