📘
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

Local Definitions

We already saw how we can use where to define local helper expressions, but there is also another way. The let-in construct also allows us to define local expressions with the syntax let <declarations> in <expression>:

sumSquares2 x y =
  let
    a = x ^ 2
    b = y ^ 2
  in
    a + b

ghci> sumSquares2 2 5
29

We can also use let -in and where in combination – for example, let's write a function that checks whether the sum of the squares of two numbers is a multiple of five:

sumSquaresM5 x y =
  let
    sum = a + b
  in
    mod sum 5 == 0 -- (mod) is the modulo operator 
  where
    a = x ^ 2
    b = y ^ 2

We know a number is a multiple of five if the remainder of its division by five is zero. A thing to note is that there is a difference between let-in and where. What we define in where declarations is accessible to any code above it. However, the declarations from the let block are only accessible in the in block of the same let-in clause. For example, we could try to calculate the remainder from the division by five in the where clause using the sumfrom the let clause, but it will not work:

sumSquaresM5 x y =
  let
    sum = a + b
  in
    res == 0
  where
    a = x ^ 2
    b = y ^ 2
    res = mod sum 5 -- the "sum" expression from let-in is not accessible here

The compilation of the above would result in an error as sum is only accessible in the in clause of the code. This means that with let-in we can create super-localised expressions that aren't accessible anywhere outside the in code block.

PreviousThe Layout RuleNextThe Infix Operator

Last updated 2 years ago

Was this helpful?