📘
HPM Education - Haskell
  • Introduction to Haskell
  • Introduction
    • Functions
    • Functional Programming vs Imperative Programming
    • Installing Haskell
    • Haskell Modules
    • Loading Modules into GHCi
    • Expressions
    • Laziness
    • Immutability
  • Types in Haskell
    • Introduction
    • Basic Types
    • Static Type Check
    • Polymorphic and Overloaded Types
    • Data Structure Types
      • Lists
        • List Functions
      • Tuples
    • Function Types
      • Curried Functions
      • Partial Application
  • Defining Functions / Working with Functions
    • The Layout Rule
    • Local Definitions
    • The Infix Operator
    • Conditionals
      • If-then-else Statements
      • MultiWayIf
      • Guarded Equations
      • Case-of Statements
    • Pattern Matching
      • Tuple Patterns
      • List Patterns
    • Lambda functions
    • Function Operators
  • List Comprehensions
    • List Comprehensions
  • Higher-order Functions
    • Introduction
    • The map Function
    • The filter Function
  • Recursion
    • Introduction
    • 4 Steps to Defining Recursive Functions
    • Recursion Practice
    • Folds
      • Fold Right (foldr)
      • Fold Left (foldl)
  • Cutom Types
    • Declaring Types
      • Type Synonyms
      • Data Declarations
      • Newtype declarations
  • Type Classes
    • Introduction
    • Basic Classes
      • Eq – Equality Types
      • Ord – ordered types
      • Show – Showable Types
      • Read – readable types
      • Num – Numeric Types
      • Integral – Integral Types
      • Fractional – Fractional Types
      • Enum – Enumeration Types
    • Derived Instances
    • Exercise – Making a Card Deck Type
  • Interactive Programming
    • Introduction
    • Input / Output Actions
    • Sequencing Actions
    • Exercise - Numbers Guessing Game
  • Functors, Applicatives and Monads
    • Introduction
    • Functors
    • Applicative Functors
    • Monads
      • Maybe Monad
      • List Monad
      • Monad Laws
  • References / Further Reading
Powered by GitBook
On this page

Was this helpful?

  1. Defining Functions / Working with Functions
  2. Conditionals

If-then-else Statements

The syntax in Haskell for if-then-else statements is:

if <CONDITION> then <EXPRESSION1> else <EXPRESSION2>

where the CONDITION must be a boolean expression. If the condition evaluates to True, then EXPRESSION1 is used, otherwise, EXPRESSION2 is used. One other thing to note here is that both expressions in the if statement must be of the same type. For example, the statement:

if True then 1 else "untrue"

is invalid because the type of 1 is Int, but the type of "untrue" is String (synonym for [Char] - a string is simply a list of characters).

Let's take a look at a simple example function using a conditional statement to decide on the final score on a race track given two arguments – the time achieved and the average time for the track in seconds:

trackScore :: Float -> Float -> String
trackScore time avgTime =
  if time < avgTime
  then "Great! Your time is " ++ show (avgTime - time) ++ " seconds 
    below average!"
  else "Your time is " ++ show (time - avgTime) ++ " seconds above 
    average."

You have probably noticed this new function show – it is a method (function) from the class Show and it is used to represent the value of a type as a string. Hence, it has the following type signature:

show :: a -> String

We will explore classes in more detail later on - for now, just know that a class comes with certain methods (functions) it supports.

All the basic types (Bool, String, Char, Int, Integer, Float and Double) are instances of the Show class which enables us to use the show function and get their representation as a string:

ghci> show 252.5
"252.2"

In our function trackScore, we consider the two cases where the given time is lower than the average time and when it is higher than the average time. But what if it is exactly the same?

ghci> trackScore 10 10
"Your time is 0.0 seconds above average."

The output is not wrong, but ideally, we would like to see a third version of the output for this particular case. We could nest another if statement in our existing code and write:

trackScore :: Float -> Float -> String
trackScore time avgTime =
  if time < avgTime
    then "Great! Your time is " ++ show (avgTime - time) ++ " seconds 
      below average!"
    else 
      if time == avgTime
        then "Your time is on par with the average time!"
        else "Your time is " ++ show (time - avgTime) ++ " seconds above 
          average."
      
ghci> trackScore 10 10
"Your time is on par with the average time!"

The output is fine now, but with every nested if statement, the code gets harder to read. Turns out there is a way to make it look nicer – with MultiWayIf.

PreviousConditionalsNextMultiWayIf

Last updated 2 years ago

Was this helpful?