Written by Isaiah Oloyede
on
on
Chapter 4: Basic Datatypes
This note captures my solutions to exercises in Chapter 4: Basic Datatypes of the book Haskell programming from first principles
Exercises: Mood swing
- The type constructor is
Mood. - If the function requires a
Moodvalue, we can only useBlahorWoot. - What is wrong with
changeMood :: Mood -> Wootis thatWootis not a type constructor. It is a data constructor. A data constructor cannot appear in the type signature, it can only appear at the term level. - Mood should not appear at the term level since it is a type constructor. Fixed function is shown below.
module ChangeMood where
data Mood = Blah | Woot deriving Show
changeMood :: Mood -> Mood
changeMood Blah = Woot
changeMood _ = Blah
Exercises: Find the mistakes
not True && trueshould benot True && Truenot (x = 6)should benot (x == 6). This will not compile because x is not defined.(1 * 2) > 5. This works without any fix.[Merry] > [Happy]should be["Merry"] > ["Happy"].[1, 2, 3] ++ "look at me!"should be['1','2','3'] ++ "look at me!".
Chapter exercises
awesome = ["Papuchon", "curry", ":)"]
alsoAwesome = ["Quake", "The Simons"]
allAwesome = [awesome, alsoAwesome]
Question 1
length has a type signature [a] -> Int. It takes a list of any type. It evaluates to a type of Int.
Question 2
length [1, 2, 3, 4, 5]gives5.length [(1, 2), (2, 3), (3, 4)]gives3. This is a list of tuples.length allAwesomegives 2.allAwesomeis a list of two values:awesomeandalsoAwesome.length (concat allAwesome)gives5.concatflattensallAwesomeand produces a list of 5 strings.
Question 3
6 / 3 works. This produces 2.0. 6 / length [1, 2, 3] returns an error because length returns an Int datatype whereas the operator (/) belongs to a Fractional typeclass which has no instance for the Int datatype. Int belongs to the Integral typeclass instead.
Question 4
We can use div function. Alternatively, we can use fromIntegral to coerce the Integral typeclass to Num typeclass. fromIntegral has a type (Integral a, Num b) => a -> b.
-- #4
-- Using a different operator
ghci> 6 `div` length [1, 2, 3]
2
-- Alternatively
ghci> 6 / fromIntegral (length [1, 2, 3])
2.0
Question 5
The type of the expression 2 + 3 == 5 is Bool. The expected result is True.
Question 6
- The type of
xinx = 5isNum a => a. The expected result is5. - The type of
x + 3 == 5isBool. The expected result isFalseifx = 5.
Question 7
length allAwesome == 2givesTrue. This works because we are comparing two values of the same datatypeInt.length [1, 'a', 3, 'b']does not work because a list cannot contain values of different datatypes.length allAwesome + length awesomegives5. This works because we are adding values of the same datatypeInt.(8 == 8) && ('b' < 'a')givesFalse. This works because we are performing a boolean And operation on two values of theBooldatatype.(8 == 8)isTrueand('b' < 'a')isFalse, thereforeTrueandFalsegivesFalse.(8 == 8) && 9does not work because we are trying to compareBoolwith a numeric datatype.
Question 8
module IsPalindrome where
isPalindrome :: (Eq a) => [a] -> Bool
isPalindrome x = x == reverse x
Question 9
module MyAbs where
myAbs :: Integer -> Integer
myAbs x = if x >= 0 then x else -x
Question 10
f :: (a, b) -> (c, d) -> ((b, d), (a, c))
f x y = (,) (snd x, snd y) (fst x, fst y)
Correcting syntax
module CorrectingSyntax where
-- #1
x :: Int -> Int -> Int
x = (+)
f :: Foldable t => t a -> Int
f xs = w `x` 1 where
w = length xs
-- #2
f' :: p -> p
f' x = x
-- #3
f'' :: (a, b) -> a
f'' (a, b) = a
Match the function names to their types
- The type of
showisShow a => a -> String(option c). - The type of
(==)isEq a => a -> a -> Bool(option b). - The type of
fstis(a, b) -> a(option a). - The type of
(+)is(+) :: Num a => a -> a -> a(option d).