Question 1: Expressions and Function Evaluation

1a)

Given this Haskell function definition:

f :: Int->Int
f x = 2*x

determine the values of the following expressions.

1b)

Assume that f has type Int->[Int], g has polymorphic type a->a, and h has polymorphic type [a]->a. Determine the types of the following expressions.

1c)

Given the integer exponentiation operator ^, i.e. x^y evaluates x raised to the power y, then calculate the values of the following expressions.

1d)

Question 2: Dragons and Type Classes

Examine the following Haskell definitions, which are relevant for this question.

 

data Dragon a = LiveDragon [a] | DeadDragon — list of a’s is record of food items eaten by dragon class Food f where poisonous :: f Bool — True means it’s bad to eat

2a)

Question

Define a function eats :: Food a => Dragon a -> a -> Dragon a which, if the first parameter is a LiveDragon, checks whether the second parameter (the food) is poisonous—if it is, then the result is a DeadDragon. > If the food is not poisonous, then the result is a LiveDragon, with the food parameter value appended to the end of the LiveDragon’s list of food. On the other hand, if the first parameter is a DeadDragon, then the result should also be a DeadDragon, whatever food is supplied as the second parameter.

2b)

Question

Declare the Int data type to be an instance of the Food type class. The only poisonous integer value is 13.

2c)

What code should be added to enable a Dragon to eat other Dragons? Assume a LiveDragon may eat a LiveDragon, but if a LiveDragon tries to eat a DeadDragon, it's poisonous, so the LiveDragon itself will become a DeadDragon.

2d)

Question

Given your definition in part (c), is it possible for a Dragon to eat itself? Would this be a sensible feature, in general?

2e)

Question

What is the motivation for the Functor type class?

2f)

Question

Explain, using appropriate source code snippets, how to make the Dragon type an instance of the Functor type class.

Question 3: Safety, Registration, and Types

3a)

Abstract

head and tail are two well-known list functions defined in Haskell’s Prelude. Their type signatures are as follows:

 

head :: [a] a tail :: [a] [a]

3b)

Abstract

You have been given a vague specification: The Republic of Ruritania is migrating its car number plate format from a sequence of five alphanumeric digits to an encoding based on: a) the locality of registration, that is the state and district the car was registered in; b) year and month of registration; and finally c) a random sequence of three alphanumeric digits. Ruritania has five states, North, South, East, West, and Capital with short codes of: N, S, E, W, and C.

Within each state there are twenty districts each known by its number. You can assume that alphanumeric digits are digits that are either numbers in the range zero to nine, or uppercase characters from the English alphabet.

(i) Write some Haskell code to represent both registration formats as a single algebraic data structure called CarReg.

3c)

Given the following type signatures for two functions operating on lists:

 

— Concatentates two lists together. append :: [a] [a] [a] — Takes the first ‘n‘ elements from a list. take :: Int [a] [a]

(ii) In the future, Haskell will support Dependent Types, allowing types to depend on values. Discuss how you can improve the definition of take using dependent types to ensure that it works as intended.