12/08/2020 Exercise (Week 5)
Exercise (Week 5)
DUE: Wed 15 July 2020 15:00:00
Controlling E ects Basic I/O (2 Marks)
CSE
Stack
Download the exercise tarball and extract it to a directory on your local machine. This tarball contains a le, called Ex04.hs , wherein you will do all of your programming.
To test your code, run the following shell commands to open a GHCi session:
$ stack repl
Configuring GHCi with the following packages: Ex04
Using main module: 1. Package ‘Ex04’ component exe:Ex04 …
GHCi, version 8.2.2: http://www.haskell.org/ghc/ 😕 for help
[1 of 2] Compiling Ex04 (Ex04.hs, interpreted)
[2 of 2] Compiling Main (Main.hs, interpreted)
Ok, two modules loaded.
*Main Ex04> capitalise “input.txt” “output.txt”
…
Calling IO actions in GHCi as above will execute them, including their side effects.
Note that you will only need to submit Ex04.hs , so only make changes to that le.
First, there is the I/O function capitalise , of the following type:
www.cse.unsw.edu.au/~cs3141/20T2/Week 05/Exercise.html
1/5
capitalise :: FilePath -> FilePath -> IO ()
This function reads the text le determined by the rst argument and capitalises each character while writing the result to the le given in the second argument. The program must read all available text from the rst le. You may nd the functions in
System.IO and Data.Char useful. More Intricate I/O (3 Marks)
Write an IO action called sumFile , of the following type:
This should retrieve two lenames which are given as a command line arguments, and read the le speci ed in the rst command line argument. This le will contain a list of integers, one per line. The sumFile action should write the sum of these numbers into the second le given as a command line argument. If you like an additional challenge, do not use any explicit recursion in the program, just the list operators etc. from the libraries (Note: There are no extra marks for this, but it is a nice puzzle).
Some hints:
● To get the command line arguments, look at
● To read les, you can just use the functions for this simple exercise;
instead of fussing around with handles.
● The standard Prelude (which is the module implicitly imported into any Haskell
programs), has a lot of functions for list manipulation.
To run your program, you can use a helper module, Main.hs , provided for you in the code bundle.
Stack
sumFile :: IO ()
System.Environment
readFile
CSE
3141
cabal build
./dist/build/Ex04/Ex04
12/08/2020
Exercise (Week 5)
In a subshell, type
should be able to invoke by typing
. For example:
to build the executable, which you
www.cse.unsw.edu.au/~cs3141/20T2/Week 05/Exercise.html
2/5
12/08/2020 Exercise (Week 5)
State and Testing IO (4 Marks)
There is a well-known guessing game where, given a number of guesses, the player attempts to guess a number that has been randomly chosen within a certain range. If the player guesses incorrectly, the only information the player receives is whether the target number is lower or higher than the player’s guess.
We will model this using Haskell, de ning a Player as a type that consists of a procedure to make a guess, and a function that returns a procedure based on the response given by the game to the player’s guess:
We allow a Player to perform arbitrary effects in order to make a guess or to handle responses. For example, the human player is de ned using IO , so as to ask the user for a number, and reports feedback to the user by printing a message to the terminal:
data Player m = Player { guess :: m Int
, wrong :: Answer -> m ()
}
data Answer = Lower | Higher
$ 3141
newclass starting new subshell for class COMP3141…
$ cabal build
Resolving dependencies…
Configuring Ex04-1.0…
Preprocessing executable ‘Ex04’ for Ex04-1.0..
Building executable ‘Ex04’ for Ex04-1.0..
[1 of 2] Compiling Ex04 ( Ex04.hs, …)
[2 of 2] Compiling Main ( Main.hs, …)
Linking dist/build/Ex04/Ex04 …
$ ./dist/build/Ex04/Ex04 “input.txt” “output.txt”
human :: Player IO
human = Player { guess = guess, wrong = wrong }
where
guess = do
putStrLn “Enter a number (1-100):”
x <- getLine
case readMaybe x of
Nothing -> guess
www.cse.unsw.edu.au/~cs3141/20T2/Week 05/Exercise.html
3/5
12/08/2020 Exercise (Week 5)
The guessing game itself is de ned generically for any monad m , so long as we can provide a Player that acts in that monad. You can play the guessing game yourself in the IO monad with the human player by calling play :
— x is the number we’re trying to guess
— n is the number of guesses we get
— p is the player
— Returns whether or not the player managed to guess correctly — in the time limit
guessingGame :: (Monad m) => Int -> Int -> Player m -> m Bool
guessingGame x n p = go n
where
go 0 = pure False
go n = do
x’ <- guess p
case compare x x' of
LT -> wrong p Lower >> go (n-1)
GT -> wrong p Higher >> go (n-1)
EQ -> pure True
play :: IO ()
play = do
x <- randomRIO (1,100)
b <- guessingGame x 5 human
putStrLn (if b then "You got it!" else "You ran out of guesses!")
Your task is to de ne a new player, ai , which plays the game automatically, by acting in the State (Int, Int) monad instead of the IO monad:
We would like it to satisfy some properties. Firstly, we would like the ai player never to repeat a guess, that is, the ai player should guess the number in at most n guesses if the number lies between 1 and n :
ai :: Player (State (Int,Int))
prop_no_repeat (Positive n)
= forAll (choose (1,n)) $ \x -> evalState (guessingGame x n ai) (1,n)
Just i -> pure i
wrong Lower = putStrLn “Lower!”
wrong Higher = putStrLn “Higher!”
www.cse.unsw.edu.au/~cs3141/20T2/Week 05/Exercise.html
4/5
12/08/2020 Exercise (Week 5)
We would further like it to play optimally – i.e. making as few guesses as possible. By bisecting the range each time, we can make a logarithmic number of guesses, proportional to the size of the initial range:
Peer review (2 Marks)
Now that you’ve all made some fantastic artworks, we’d like each of you that submitted a picture to review one other student’s picture. To do this, just log in to the peer review form here, and answer the questions the form asks you. Make sure you review carefully and kindly, because your review will be posted on the gallery page for that picture, and your identity is revealed to the person who made the image. To check the reviews for your own artworks, you can click here.
Submission instructions
You can submit your exercise by typing:
on a CSE terminal, or by using the give web interface. Your le must be named Ex04.hs (case-sensitive!). A dry-run test will partially autotest your solution at
submission time. To get full marks, you will need to perform further testing yourself.
prop_optimality (Positive n)
= forAll (choose (1,n)) $ \x ->
evalState (guessingGame x (bound n) ai) (1,n)
where bound n = ceiling (logBase 2 (fromIntegral n)) + 1
$ give cs3141 Ex04 Ex04.hs
www.cse.unsw.edu.au/~cs3141/20T2/Week 05/Exercise.html
5/5