Introduction to Functional Programming – Lab 4B “Famous”TDA555 / DIT440, LP1 2018
Home | Schedule | Labs | Lectures | Exercises | Exam | About | FAQFire | WaitList | Slack | TimeEdit | YouTube | Links
Introduction to Functional Programming – Lab 4B “Famous”TDA555 / DIT440, LP1 2018
Home | Schedule | Labs | Lectures | Exercises | Exam | About | FAQFire | WaitList | Slack | TimeEdit | YouTube | Links

Lab Assignment 4B: Famous

Goal & Purpose

Watch this short video showing the playing of a small game (there is no audio). This is the game you will implement in this lab. Although the game is totally lame, it will teach you something about working with IO as well as recursive data types.

Deadline

Must be submitted before Friday, October 26 at midnight (2018)

The submission instructions are similar to those for Lab 4A.

Requirements & Recommendations

We have the following requirements and/or recommendations (R1 - R6) for implementing the game:

R1

Define a data type QA to represent “Question-Answer” decision trees like the following:
Decision Tree Example
The smallest trees just give the name of a person. Larger trees are built with a question together with two sub-trees, one for the yes answer and one for the no answer. You can assume that all questions are yes-no so you do not need to represent the “yes” and “no” explicitly.

Add deriving (Show, Read); The show function will be used when you store a decision tree into a file. The Read class will give you a function read :: String -> QA which will help you when you want to build instructions to read a decision tree back from that file.

R2
Use a representation of the decision tree pictured above as your default tree, to be used when there is no file (famous.qa).
R3

Once we have a decision tree (either from the file or using the default tree), we start playing a round of the game by walking down the tree, asking questions as we go along. Once you get to a person then the guess has been decided.

So suppose we have played the default decision tree as follows:
Is she from Europe? yes
Is she a scientist? no
My guess: Is it Queen Elisabeth II? no
OK - you won this time.
At this point the game will continue (the text in bold face is typed by the player):
Just curious: Who was your famous person? Theresa May
Give me a question for which the answer for "Theresa May" is "yes"
and the answer for "Queen Elisabeth II" is "no".
Is she a politician?

At this point the game should construct the tree pictured below:
Extended decision tree
we recommend that this process is implemented using a recursive function

play :: QA -> IO QA

Once play returns the new decision tree (which will be unchanged if the computer guessed the right answer) then it can be stored back into the file.

R4

About IO. If we use readFile :: FileName -> IO String and the file does not exist then there will be an error and the program will crash. This is not what we want! Here you should use

tryIOError :: IO a -> IO (Either IOError a)
from standard module System.IO.Error Using tryIOError (readFile ...), we turn an IO instruction that possibly generates an error into an IO instruction that never generates any error, but instead returns a value that tells us whether or not there was an error. Look at the documentation for the datatypes Either and IOError for more information.
R5
More about IO. Most operating systems do not write things directly on the screen when the program tells them to. Instead, they wait until a whole line is printed to the screen, and then they actually print it. This can be a nuisance when a question is printed on the screen, and the user has to type the answer on the same line (as we want in this game). To avoid the question not being printed on the screen, we tell the operating system to “flush” the output of the program, i.e. print everything on the screen that we want to print on the screen, not waiting for the end of the current line. A haskell instruction hFlush stdout will do this for us, so use it after using putStr ... to make sure things get printed right away. You will need to include module System.IO for this.
R6

Most of this program will be IO instructions, but that does not mean that you should not think about defining useful functions which you can reuse in several places, and which help to give your program some nice structure.

As a hint, think about defining a function

question :: String -> IO String

which asks a question and returns the answer typed by the user.

Using this, you can define

yesNoQuestion :: String -> IO Bool

which asks a yes-no question (repeatedly if needed) until it gets either answer “yes” or “no”, and it returns True when the answer was yes, and False when the answer was no. This can be used in several places in your program.

R6
The whole game should be defined as main :: IO() Then you can run the game from the terminal by typing runhaskell Famous (which does the same as loading the file in ghci and typing main).

Submission Instructions

You must submit using the Fire system preferably in groups of 3.

You should only submit: your version of Famous.hs. Do not upload any other files.

Before you submit your code, Clean It Up! Remember, submitting clean code is Really Important, and simply the polite thing to do. After you feel you are done, spend some time on cleaning your code; make it simpler, remove unneccessary things, etc. We will reject your solution if it is not clean. Clean code:

  • Does not have long lines (< 78 characters) or tab characters

  • Has a consistent layout

  • Has type signatures for all top-level functions

  • Has good comments where needed

  • Has no junk (junk is unused code, commented code, unneccessary comments)

  • Has no overly complicated function definitions

  • Does not contain any repetitive code (copy-and-paste programming)
  • We expect you to run the hlint command on your program and follow the advice given. If you do not understand the advice you should include your original code in comments in your submission. (You are welcome to use it for part I, but unless you have read about higher-order functions you probably won’t understand the advice.)

    Change Log