Commit f7859b4a authored by Christoph Ruegge's avatar Christoph Ruegge
Browse files

Typo

parent d8ca6b17
%% Cell type:markdown id: tags:
# Exercises: io
## problem 1
Remember the phone book
```haskell
phonebook :: [(String, String)]
phonebook = [("Alice", "01234"),("Bob", "54321"), ("Jochen", "13243")]
```
Write a program that interactively asks for a user and returns their number.
%% Cell type:code id: tags:
``` haskell
```
%% Cell type:markdown id: tags:
## problem 2
implement a type for a person, which contains name, age, gender, job (use nice types inside the person also, e.g. create a type for the gender) and make an instance of `Show` for it.
Then get information from the user and return a `Person`
%% Cell type:code id: tags:
``` haskell
```
%% Cell type:markdown id: tags:
## problem 3
read a file, which contains attributes for a `Person` in every line and returns the resulting list of persons. Create a fitting file yourself.
%% Cell type:code id: tags:
``` haskell
```
%% Cell type:markdown id: tags:
## problem 4
extend problem 1 such that wrong inputs are caught and are asked again. Use the `Maybe`-Monad to accomplish this task
%% Cell type:code id: tags:
``` haskell
```
%% Cell type:markdown id: tags:
## problem 5
use the csv-module `cassava` https://github.com/tibbe/cassava to read `Person`s from a csv-file, e.g. '../data/persons.txt'.
make the reading of the file safe (no runtime exceptions)
%% Cell type:code id: tags:
``` haskell
```
%% Cell type:markdown id: tags:
## problem 6
implement a game for guessing numbers, which works with the following scheme:
think of a number between 1 and 100!
is it 50? _lesser_
is it 50? _less_
is it 25? _greater_
...
is it 42? _yes_
finished.
%% Cell type:code id: tags:
``` haskell
```
......
%% Cell type:markdown id: tags:
# Exercises: io
## problem 1
Remember the phone book
```haskell
phonebook :: [(String, String)]
phonebook = [("Alice", "01234"),("Bob", "54321"), ("Jochen", "13243")]
```
Write a program that interactively asks for a user and returns their number.
%% Cell type:code id: tags:
``` haskell
import Data.Maybe
phonebook :: [(String, String)]
phonebook = [("Alice", "01234"),("Bob", "54321"), ("Jochen", "13243")]
do putStrLn "Enter a name: "
name <- getLine
putStrLn $ fromMaybe "Not found" $ do
num <- lookup name phonebook
return $ "The number is " ++ num
```
%% Cell type:markdown id: tags:
## problem 2
implement a type for a person, which contains name, age, gender, job (use nice types inside the person also, e.g. create a type for the gender) and make an instance of `Show` for it.
Then get information from the user and return a `Person`
%% Cell type:code id: tags:
``` haskell
data Gender = M | F deriving (Eq,Show)
data Person = Person {
name :: String,
age :: Int,
gender :: Gender,
job :: String
} deriving (Eq)
instance Show Person where
show x = "My name is " ++ name x ++ " and I'm " ++ show (age x) ++ " years old."
```
%% Cell type:code id: tags:
``` haskell
getPerson :: IO Person
getPerson = do
putStrLn "Name:"
name <- getLine
putStrLn "Age:"
age <- readLn :: IO Int
putStrLn "Gender:"
gstr <- getLine
let gender = if 'M' == head gstr then M else F
putStrLn "Job:"
job <- getLine
return (Person name age gender job)
```
%% Cell type:code id: tags:
``` haskell
getPerson
```
%% Cell type:markdown id: tags:
## problem 3
read a file, which contains attributes for a `Person` in every line and returns the resulting list of persons. Create a fitting file yourself.
%% Cell type:code id: tags:
``` haskell
import System.IO
import Data.List.Split
readPerson line = Person (head attr) (read (attr!!1)) gender (attr!!3)
where
attr = splitOn "," line
gender = if 'M' == (head attr!!2) then M else F
-- IO context
pf <- readFile "../data/persons.txt"
fl = lines pf
map readPerson fl
```
%% Cell type:markdown id: tags:
## problem 4
extend problem 1 such that wrong inputs are caught and are asked again. Use the `Maybe`-Monad to accomplish this task
%% Cell type:code id: tags:
``` haskell
import Data.Maybe
import Control.Monad
phonebook :: [(String, String)]
phonebook = [("Alice", "01234"),("Bob", "54321"), ("Jochen", "13243")]
getOneNamesNumber :: IO (String, String)
getOneNamesNumber = do
putStrLn "Enter a name: "
name <- getLine
case lookup name phonebook of
Nothing -> getOneNamesNumber
Just num -> return (name,num)
-- IO context
(name,number) <- getOneNamesNumber
print $ name ++ "'s number is " ++ number ++ "."
```
%% Cell type:markdown id: tags:
## problem 5
use the csv-module `cassava` https://github.com/tibbe/cassava to read `Person`s from a csv-file, e.g. '../data/persons.txt'.
make the reading of the file safe (no runtime exceptions)
%% Cell type:code id: tags:
``` haskell
{-# LANGUAGE OverloadedStrings #-}
import Data.Csv
import Control.Monad
import Data.Vector (Vector(..))
import qualified Data.ByteString.Lazy as BL
instance FromField Gender where
parseField g
| g == "M" = pure M
| g == "F" = pure F
| otherwise = mzero
instance ToField Gender where
toField M = "M"
toField F = "F"
instance FromRecord Person where
parseRecord v
| length v == 4 = Person <$> v .! 0 <*> v .! 1 <*> v .! 2 <*> v .! 3
| otherwise = mzero
instance ToRecord Person where
toRecord (Person name age gender job) = record [
toField name, toField age, toField gender, toField job]
csvData <- BL.readFile "../data/persons.txt"
print csvData
decode NoHeader csvData :: Either String (Vector Person)
```
%% Cell type:markdown id: tags:
## problem 6
implement a game for guessing numbers, which works with the following scheme:
think of a number between 1 and 100!
is it 50? _lesser_
is it 50? _less_
is it 25? _greater_
...
is it 42? _yes_
finished.
%% Cell type:code id: tags:
``` haskell
game :: String -> Int -> Maybe Int
game "lesser" x = Just $ div x 2 -- better logic possible
game "less" x = Just $ div x 2 -- better logic possible
game "greater" x = Just $ x + div x 3
game "yes" x = Just x
game _ x = Nothing
```
%% Cell type:code id: tags:
``` haskell
oneGuess :: Int -> IO ()
oneGuess x = do
putStrLn $ "is it " ++ show x ++ "? "
ans <- getLine
let newx = game ans x
print newx
case newx of
Nothing -> do
putStrLn "please answer with 'lesser', 'greater' or 'yes'!"
putStrLn "please answer with 'less', 'greater' or 'yes'!"
oneGuess x
Just n -> if n == x
then putStrLn "finished."
else oneGuess n
putStrLn "Think of a number between 1 and 100!"
oneGuess 50
```
%% Cell type:code id: tags:
``` haskell
```
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment