text: Haskell offers several ways of expressing a choice between different values. We explored some of them in the Haskell Basics chapters. This section will bring together what we have seen thus far, discuss some finer points, and introduce a new control structure.
  Contents
  if and guards revisitedEdit) as in many imperative languages.[1] As a consequence, the else is mandatory in Haskell.. With guards, the example above is a little neater:
  describeLetter :: Char -> String describeLetter c | c >= 'a' && c <= 'z' = "Lower case" | c >= 'A' && c <= 'Z' = "Upper case" | otherwise = "Not an ASCII letter"
  Remember that
  otherwise is just an alias to
  True, and thus the last guard is a catch-all, playing the role of the final
  else of the
  if expression.
  Guards are evaluated in the order they appear. Consider a set up like. (Of course, if neither pattern matches or neither predicate is true for the matching pattern there will be a runtime error. Regardless of the chosen control structure, it is important to ensure all cases are covered.)
  Embedding if expressionsEdit, more complicated one-line
  if expressions would be hard to read, making
  let and
  where attractive options in such cases.
  case expressionsEdit beginning of the line containing. Using case syntax to bind variables to the head and tail of our list is convenient here, but you could also do this with an if-statement (with a condition of
  null str to pick the empty string case). (although the resulting definition is not as readable).
  Controlling actions, revisitedEdit
  In the final part of this chapter, we will introduce a few extra points about control structures while revisiting the discussions in the "Simple input and output" chapter. There, in the Controlling actions section, we used the following function to show how to execute actions conditionally within a
  do block using
  if expressions:
  doGuessing num = do putStrLn "Enter your guess:" guess <- getLine if (read guess) < num then do putStrLn "Too low!" doGuessing num else if (read guess) > num then do putStrLn "Too high!" doGuessing num else do putStrLn "You Win!"
  We can write the same
  doGuessing function using a case statement. To do this, we first introduce the Prelude function
  compare which takes two values of the same type (in the
  Ord class) and returns a value of type
  Ordering — namely one of
  GT,
  LT,
  EQ, depending on whether the first!"
  The dos after the
  ->s are necessary on the first two options, because we are sequencing actions within each case.
  A note about
  returnEdit
  Now, we are going to dispel a possible source of confusion. In a typical imperative language (C, for example) an implementation of
  doGuessing might look like the following (if you don't know C, don't worry with the details,, and the
  if putStrLn "Too low!"; doGuessing num else do putStrLn "Too high!"; doGuessing num
  ... but it won't work! If you guess correctly, the function will first print "You win!," but it will not exit at the
  return (). Instead, the program will continue to the
  if expression and check] The
  return () in particular
  - ↑ If you have programmed in C or Java, you will recognize Haskell's if/then/else as an equivalent to the ternary conditional operator
  ?:.
  - ↑ To see why this is so, consider our discussion of matching and binding in the Pattern matching section
  - ↑ Thus,
  casestatements are type as
  getLine. Do not worry if that doesn't make sense for now; you will understand what
  returnreally does when we actually start discussing monads further ahead on the book.