Skip to content

Commit 7a366c9

Browse files
committed
Add solutions to the typeclass chapter
1 parent 6af2d1e commit 7a366c9

File tree

7 files changed

+223
-0
lines changed

7 files changed

+223
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Does it typecheck?
2+
3+
1. The following code
4+
```haskell
5+
data Person = Person Bool
6+
7+
printPerson :: Person -> IO ()
8+
printPerson person = putStrLn (show person)
9+
```
10+
does not typecheck because `Person` has no instance of `Show`.
11+
12+
2. The following code
13+
```haskell
14+
data Mood = Blah
15+
| Woot deriving Show
16+
17+
settleDown x = if x == Woot
18+
then Blah
19+
else x
20+
```
21+
does not typecheck because `Mood` has no instance of `Eq`.
22+
23+
3. Suppose that we were able to get `settleDown` to typecheck, then
24+
a) it accepts `Blah` and `Woot` as input
25+
b) `settleDown 9` gives an error saying *No instance for (Num Mood) arising from the literal '9'*.
26+
c) `Blah > Woot` gives an error because `Mood` has no instance of `Ord`.
27+
28+
4. The following code
29+
```haskell
30+
type Subject = String
31+
type Verb = String
32+
type Object = String
33+
34+
data Sentence = Sentence Subject Verb Object
35+
deriving (Eq, Show)
36+
37+
s1 = Sentence "dogs" "drool"
38+
s2 = Sentence "Julie" "loves" "dogs"
39+
```
40+
does typecheck.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Given a datatype declaration, what can we do?
2+
3+
Given the following datatype definitions:
4+
```haskell
5+
data Rocks = Rocks String deriving (Eq, Show)
6+
data Yeah = Yeah Bool deriving (Eq, Show)
7+
data Papu = Papu Rocks Yeah deriving (Eq, Show)
8+
```
9+
10+
1. `phew = Papu "chases" True` does not typecheck because `"chases"` is not of type `Rocks` and `True` is not of type `Yeah`.
11+
12+
2. `truth = Papu (Rocks "chomskydoz") (Yeah True)` typechecks.
13+
14+
3. The following
15+
```haskell
16+
equalityForall :: Papu -> Papu -> Bool
17+
equalityForall p p' = p == p'
18+
```
19+
typechecks.
20+
21+
4. The following
22+
```haskell
23+
comparePapus :: Papu -> Papu -> Bool
24+
comparePapus p p' = p > p'
25+
```
26+
does not typecheck because `Papu` has no instance of `Ord`.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Match the types
2+
3+
1. For the following definition
4+
```haskell
5+
i :: Num a => a
6+
i = 1
7+
```
8+
we cannot replace the type signature with `i :: a`.
9+
Indeed, `i :: a` means that `i` could be resolved as **any** type,
10+
it is clearly impossible to resolve `1` as `String`.
11+
12+
2. In
13+
```haskell
14+
f :: Float
15+
f = 1.0
16+
```
17+
we cannot replace the type signature by `f :: Num a => a`.
18+
Again, `f :: Num a => a` means `f` could be **any** type which
19+
has instance of `Num`.
20+
`1.0` clearly cannot be a `Integer`.
21+
Instead, `f :: (Fractional a) => a` **typechecks**
22+
(which answers the question 3).
23+
24+
4. In
25+
```haskell
26+
f :: Float
27+
f = 1.0
28+
```
29+
we can replace the type signature by `f :: (RealFrac a) => a`.
30+
5. In
31+
```haskell
32+
freud :: a -> a
33+
freud x = x
34+
```
35+
we can replace the type signature by `freud :: Ord a => a -> a`.
36+
37+
6. In
38+
```haskell
39+
freud' :: a -> a
40+
freud' x = x
41+
```
42+
we can replace the type signature by `freud' :: Int -> Int`.
43+
44+
7. In
45+
```haskell
46+
myX = 1 :: Int
47+
48+
sigmund :: Int -> Int
49+
sigmund x = myX
50+
```
51+
we **cannot** write `sigmund :: a -> a` because `myX :: Int` could
52+
**not** be resolved as for example `String`.
53+
Similarly, `sigmund :: (Num a) => a -> a` does **not** typecheck
54+
(which answers the question 8).
55+
56+
9. In
57+
```haskell
58+
jung :: Ord a => [a] -> a
59+
jung xs = head (sort xs)
60+
```
61+
we can write `jung :: [Int] -> Int`.
62+
63+
10. In
64+
```haskell
65+
young :: [Char] -> Char
66+
young xs = head (sort xs)
67+
```
68+
we can write `young :: Ord a => [a] -> a`.
69+
70+
11. In
71+
```haskell
72+
mySort :: [Char] -> [Char]
73+
mySort = sort
74+
75+
signifier :: [Char] -> Char
76+
signifier xs = head (mySort xs)
77+
```
78+
we cannot write `signifier :: Ord a => [a] -> a` because `mySort` expects `[Char]` and returns `[Char]`.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Multiple Choice
2+
3+
1. The `Eq` class c) makes equality tests possible.
4+
5+
2. The typeclass `Ord` b) is a subclass of `Eq`.
6+
7+
3. Suppose the typeclass `Ord` has an operator `>`. Then the type of
8+
`>` is a) `Ord a => a -> a -> Bool`.
9+
10+
4. In `x = divMod 16 12`, c) the type of `x` is a tuple.
11+
12+
5. The typeclass `Integral` includes a) `Int` and `Integer` numbers.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module Typeclasses.ChapterExercises.TypeKwonDo where
2+
3+
-- Question 1
4+
chk :: Eq b => (a -> b) -> a -> b -> Bool
5+
chk f a = (==) (f a)
6+
7+
-- Question 2
8+
arith :: Num b => (a -> b) -> Integer -> a -> b
9+
arith f _ = f
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Intermission: Exercises
2+
3+
1. `max (length [1, 2, 3]) (length [8, 9, 10, 11, 12]) = 5`
4+
5+
2. `compare (3 * 4) (3 * 5) = LT`
6+
7+
3. `compare "Julie" True` gives an error because `"Julie" :: String` and `True :: Bool`
8+
9+
4. `(5 + 3) > (3 + 6) = False`
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
module Typeclasses.WritingTypeclassInstances.IntermissionExercises where
2+
3+
-- Question 1
4+
data TisAnInteger = TisAn Integer
5+
6+
instance Eq TisAnInteger where
7+
TisAn x == TisAn y = x == y
8+
9+
-- Question 2
10+
data TwoIntegers = Two Integer Integer
11+
12+
instance Eq TwoIntegers where
13+
Two x y == Two x' y' = x == x' && y == y'
14+
15+
-- Question 3
16+
data StringOrInt = TisAnInt Int | TisAString String
17+
18+
instance Eq StringOrInt where
19+
TisAnInt x == TisAnInt y = x == y
20+
TisAString x == TisAString y = x == y
21+
_ == _ = False
22+
23+
-- Question 4
24+
data Pair a = Pair a a
25+
26+
instance (Eq a) => Eq (Pair a) where
27+
Pair a a' == Pair b b' = a == b && a' == b'
28+
29+
-- Question 5
30+
data Tuple a b = Tuple a b
31+
32+
instance (Eq a, Eq b) => Eq (Tuple a b) where
33+
Tuple a b == Tuple a' b' = a == a' && b == b'
34+
35+
-- Question 6
36+
data Which a = ThisOne a | ThatOne a
37+
38+
instance (Eq a) => Eq (Which a) where
39+
ThisOne a == ThisOne a' = a == a'
40+
ThatOne a == ThatOne a' = a == a'
41+
_ == _ = False
42+
43+
-- Question 7
44+
data EitherOr a b = Hello a | Goodbye b
45+
46+
instance (Eq a, Eq b) => Eq (EitherOr a b) where
47+
Hello a == Hello a' = a == a'
48+
Goodbye b == Goodbye b' = b == b'
49+
_ == _ = False

0 commit comments

Comments
 (0)