Given the following datatype, answer the following questions:
data Mood = Blah | Woot deriving Show
- What is the type constructor, or name of this type?
Answer: Mood - If the function requires a
Mood
value, what are the values you could possibly use?
Answer:Blah
andWoot
- We are trying to write a function
changeMood
to change Chris's mood instantaneously. It should act likenot
in that, given one value, it returns the other value of the same type. So far, we've written a type signaturechangeMood :: Mood -> Woot
. What's wrong with that?
Answer: The return type is a value constructor and not a type constructor. The correct type signature ischangeMood :: Mood -> Mood
. - Now we want to write the function that changes his mood. Given an input
Mood
, it should return the oppositeMood
. Fix any mistakes and complete the function:
>:{
> changeMood :: Mood -> Mood
> changeMood Blah = Woot
> changeMood _ = Blah
>:}
Wrapping the lines in :{
and :}
allows you to write multi-line code in the REPL.
- Enter all of the above -- datatype (including the
deriving Show
bit), your corrected type signature, and the corrected function into a source file. Load it and run it in GHCi to make sure you got it right.
Solution file
The following liens of code may have mistakes. Fix them!
not True && true
Answer:not True && True
Note: Keep in mind that while the results would be the same, this expression is not exactly the same asnot (True && True)
. Named functions have higher precedence than operators. Thus,not True && False
isFalse
whilenot (True && False)
isTrue
.not (x = 6)
Answer:not (x == 6)
, provided thatx
is in scope.(1 \* 2) > 5
Answer: This is correct[Merry] > [Happy]
Answer:["Merry"] > ["Happy"]
unlessMerry
andHappy
are variables in scope.[1, 2, 3] ++ "look at me!"
Answer:"1, 2, 3 " ++ "look at me!"
Note: The infix operator++
has the type[a] -> [a] -> [a]
. This means that the elements of the two lists must be of the same type.
For the following exercises, you need to have the following 3 variables in scope:
awesome = ["Papuchon", "curry", ":)"]
also = ["Quake", "The Simons"]
allAwesome = [awesome, also]
length
is a function that takes a list and returns a result that tells how many items are in the list:
- Given the definition of
length
above, what is the type signature?
Answer:length :: [a] -> Integer
- What are the results of the following expressions?
a.length [1, 2, 3, 4, 5]
Answer:5
b.length [(1, 2), (2, 3), (3, 4)]
Answer:3
c.length allAwesome
Answer:2
d.length (coancat allAwesome)
Answer:5
- Given what we know about numeric types and the type signature of
length
, look at these two expressions. One works and one returns an error. Determine which will return an error and why.
Presule> 6 / 3
-- and
Predule> 6 / length [1, 2, 3]
Answer: 6 / length [1, 2, 3]
returns an error. Reason is that (/) :: Fractional a => a -> a -> a
means that both arguments to /
must be Fractional
values, but length
returns an Int
value. We could demonstrate that by forcing a number value to be an Int
: 1 / 2 :: Int
, throws the same error.
-
How can you fix the broken code from the preceding exercise using a different division function/operator?
Answer:div 6 $ length [1, 2, 3]
-
What is the type of the expression 2 + 3 == 5? What would we expect as a result?
Answer:Bool
is the type and we can expect it to evaluate toTrue
. -
What is the type of the expected value of the following?
Prelude> x = 5
Prelude> x + 3 == 5
Answer: Bool
is the type and we can expect it to evaluate to False
.
- Below are some bits of code. Which will work? Why or why not? If they will work, what value would these reduce to?
Prelude> length allAwesome == 2
Answer: This will work and evaluate to True
. Since length
has precedence over ==
the expression is equivalent to: length [awesome, also] $ == 2 -> 2 == 2 -> True
.
Prelude> length [1, 'a', 3, 'b']
Answer: This won't work. Lists must contain elements of the same type. There are Char
s and Int
s in the list.
Prelude> length allAwesome + length awesome
Answer: This will work and evaluate to 5
. Since length
has precedence over +
the expression is equivalent to: (length allAwesome) + (length awesome) -> (length [awesome, also]) + (length ["Papuchon", "curry", ":)"]) -> 2 + 3 -> 5
.
Prelude> (8 == 8) && ('b' < 'a')
Answer: This will work and evaluate to False
. (True) && (False) -> False
Prelude> (8 == 8) && 9
Answer: This won't work. The &&
operator has type Bool -> Bool -> Bool
while the right hand side is an Int
.
- Write a function that tells you whether or not a given String is a palindrome. Here you'll want to use a function called
reverse
. A built-in function that does what it sounds like.
isPalindrome :: (Eq a) => [a] -> Bool
isPalindrome x = x == reverse x
- Write a function to return the absolute value of a number using if-then-else.
myAbs :: Integer -> Integer
myAbs x = if x < 0 then -x else x
- Fill in the definition of the following function, using
fst
andsnd
:
f :: (a, b) -> (c, d) -> ((b, d), (a, c))
f x y = ((snd x, snd y), (fst x, fst y))
In the following examples, you'll be shown syntactically incorrect code. Type it in and try to correct it in your text editor, validating it with GHC or GHCi.
- Here, we want a function that adds 1 to the length of a string argument and returns that result.
x = (+)
F xs = w 'x' 1
where w = length xs
Problems with this code:
x
represents the prefix add operator(+)
. It can't be put into single quotes which makes it aChar
and also must precede both its arguments. Alternatively, we can putx
in backticks `x
` instead of single quotes which renders the prefix operator to an infix.F
is supposed to be a function. Functions in Haskell can't start with a capital letter.
Correct code:
x = (+)
f xs = x w 1
where w = length xs
-- or
f xs = w `x` 1
where w = length xs
- This is supposed to be the identity function,
id
.
\X = x
Problems with this code:
- Either this is supposed to be a lambda function, in wich case we have to use an
->
instead of=
and also make the function parameter lower case - Or it is supposed to be a named function like
id
. In that case we don't use\
, the function must have a name andX
must be lower case.
\x -> x
-- or
myId :: a -> a
myId x = x
- When fixed, this function will return 1 from the value (1, 2)
f (a b) = A
There are two approaches to solve this:
- Using the built-in
fst
function - Using pattern matching
f :: (a, b) -> a
f x = fst x
--or
f :: (a, b) -> a
f (a, b) = a
-
Which of the following types is the type of
show
?
a.show a => a -> String
b.Show a -> a -> String
c.Show a => a -> String
Answer: c -
Which of the following types is the type of
(==)
?
a.a -> a -> Bool
b.Eq a => a -> a -> Bool
c.Eq a -> a -> a -> Bool
d.Eq a => A -> Bool
Answer: b -
Which of the following types is the type of
fst
?
a.(a, b) -> a
b.b-> a
c.(a, b) -> b
Answer: a -
Which of the following types is the type of
(+)
?
a.(+) :: Num a -> a -> a -> Bool
b.(+) :: Num a => a -> a -> Bool
c.(+) :: num a => a -> a -> a
d.(+) :: Num a => a -> a -> a
f.(+) :: a -> a -> a
Answer: d