Question 1: Expressions and Function Evaluation

1a)

For each of the following Haskell expressions, write down the result of evaluation.

[]

[[],[],[]] — more tricky than previous case! Don’t accept single empty list here.

[('a','a'), ('b','b'), ('c', 'c')] — i.e. a list of (Char,Char) pairs

(v) let f = \x->x in f (f 1, f 'a')

(1,a) — since f is polymorphic, and late-bound, although students don’t need to state this explicitly.

1b)

(i) foldl (+)0 [1,2,3]

(ii) foldr (+)0 [1,2,3]

1c)

Question

Consider a function op :: Int->Int->Int. What property must the op function have, so the results of foldl op and foldr op are equal?

1d)

Question

(d) Consider function concat :: [[a]] -> [a] which takes a list of lists of elements and returns a list of elements. For instance, concat [[1], [2], [3,4,5]] evaluates to [1,2,3,4,5] and concat ["hello", "world"] evaluates to `“helloworld”. Write a recursive definition for the concat function that uses pattern matching on the list data structure.

1e)

Question

(e) Write a point-free definition for the concat function.

Question 2: Monads and Pirate Ships

2a)

Question

What is the type of the monadic bind operator (>>=) in Haskell?

Monad m m a (a m b) m b — 1 mark for type constraint, then 1 for each value type

2b)

Study the following type declarations.

 

type Treasure = Int — count num. treasure chests data PirateShip = PirateShip Treasure — e.g. (PirateShip 2) is ship with two treasure chests


Suppose that a PirateShip can carry a maximum cargo of three treasure chests, without sinking. We want to define a function called addTreasure, which takes a PirateShip parameter and evaluates to a Maybe PirateShip result. If a PirateShip value x currently has fewer than three treasure chests, then addTreasure x evaluates to a PirateShip with one more treasure chest, wrapped in a Just instance. However if the input parameter x already has the maximum three treasure chests, then addTreasure x evaluates to Nothing which denotes that the ship has sunk.

Question 3: Binary Trees and Twistable Typeclasses

3a)

Abstract

Here is a definition of a binary tree datatype in Haskell.

 

data Tree a = Leaf | Node a (Tree a) (Tree a)

Question

Write a function countNodes :: Tree a -> Int that returns the number of Nodes in a binary tree. For instance, countNodes (Node 1 Leaf (Node 1 Leaf Leaf)) evaluates to 2.

3b)

Question

Write a function mirror :: Tree a -> Tree a that returns the mirror image of a binary tree.

3c)

Abstract

Here is a definition of a typeclass in Haskell. We will use this typeclass to characterize finite data structures that we can reverse, in some sense.

 

class Twistable t where twist :: tt size :: tInt

is an instance of the Twistable typeclass.

(iii) Here are the properties that twist must satisfy:

  1. If the data to be twisted has size 0, then the twisted data has the same value as the original data.
  2. The twisted data always has the same size as the original data.
  3. Twist applied twice (i.e. twist (twist x) ) is equal to the identity function. Now express these three properties as quickcheck specifications for arbitrary lists [a], with appropriate type signatures.