Haskell/Solutions/Simple input and output

From Wikibooks, the open-content textbooks collection

Jump to: navigation, search

← Back to Simple input and output



[edit] Actions

Exercises

Write a program which asks the user for the base and height of a triangle, calculates its area and prints it to the screen. The interaction should look something like:

The base?
3.3
The height?
5.4
The area of that triangle is 8.91
Hint: you can use the function read to convert user strings like "3.3" into numbers like 3.3 and function show to convert a number into string.
 main = do
   putStrLn "The base?"
   base <- getLine
   putStrLn "The height?"
   height <- getLine
   putStrLn ("The area of that triangle is " ++ show (0.5 * read base * read height))

[edit] Controlling Actions

Exercises

What does the following program print out?

main =
 do x <- getX
    putStrLn x

getX =
 do return "hello"
    return "aren't"
    return "these"
    return "returns"
    return "rather"
    return "pointless?"
Why?

Executing main will print "pointless?". Remember that the value of a sequence of IO actions is the same as the value of the last action in the sequence. getX can also be written as:

 getX =
  do return "pointless?"

or even shorter, as:

 getX = return "pointless?"

As a result, x in the main function has the value "pointless?", which will then be written to the screen.

Exercises

Write a program that asks the user for his or her name. If the name is one of Simon, John or Phil, tell the user that you think Haskell is a great programming language. If the name is Koen, tell them that you think debugging Haskell is fun (Koen Classen is one of the people who works on Haskell debugging); otherwise, tell the user that you don't know who he or she is.

Write two different versions of this program, one using if

statements, the other using a case statement.

With if-statements:

 main = do
   putStrLn "Hello, what is your name?"
   name <- getLine
   if name == "Simon" || name == "John" || name == "Phil"
      then putStrLn "I think Haskell is a great programming language."
      else if name == "Koen"
              then putStrLn "I think debugging Haskell is fun."
              else putStrLn "Sorry, I don't know you."

With case

 main = do
   putStrLn "Hello, what is your name?"
   name <- getLine
   case name of
     "Simon" -> greatlanguage
     "John"  -> greatlanguage
     "Phil"  -> greatlanguage
     "Koen"  -> putStrLn "I think debugging Haskell is fun."
     _       -> putStrLn "Sorry, I don't know you."
 
 greatlanguage = putStrLn "I think Haskell is a great programming language."

[edit] Actions under the microscope

Exercises
  1. Why does the unsweet version of the let binding require an extra do keyword?
  2. Do you always need the extra do?
  3. (extra credit) Curiously, let without in is exactly how we wrote things when we were playing with the interpreter in the beginning of this book. Why can you omit the in keyword in the interpreter, when you'd have to put it in when typing up a source file?
  1. A let name = value in thing binding has the same type as thing. Because we want the binding to be an IO action, the thing needs to be an IO action, so we need a do keyword.
  2. No, not always. Just as in "normal" code, you can omit the do keyword if there's only one IO action following it.
  3. The GHCi interpreter is like one big do-block with some extra magic, so that it convert normal expressions to IO-actions. As in any do-block, you can omit the in keyword.