πŸ“˜
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. Introduction

Functions

In Haskell, functions work exactly as they do in mathematics. In mathematics, functions define the unambiguous dependence of the output value to its arguments, i.e., they map the input values to the output. This means that for any combination of arguments, there can only be one result. Let’s look at a simple example of a function that takes one argument and multiplies it by three:

f(x)=3βˆ—xf (x) = 3 * xf(x)=3βˆ—x

For any input value x, there is only one possible output:

f(2)=6f (2) = 6f(2)=6
f(βˆ’5)=βˆ’15 f ( -5) = -15f(βˆ’5)=βˆ’15

This is exactly what we mean when we say Haskell is a purely functional programming language – because it focuses on pure functions whose output values are entirely determined by their arguments. This means that there are no side-effects to functions in Haskell, a function with the same arguments will always produce the same result no matter what else is going on in the program it is in, which makes them very reliable.

In other words, Haskell functions do not allow anything besides simply taking inputs from their arguments and producing a return value, so things like printing on screen, reading from and writing to files are off the table for Haskell functions. However, that would mean Haskell cannot be very useful, and that is why it is still possible to integrate these important and useful features through the use of Monads (we will not touch Monads for some time, but for now just trust me that Haskell can have very real applications – after all, Cardano is built with Haskell).

In Haskell, we can define a function by using an equation that specifies:

  1. The function name

  2. The names of its arguments

  3. The function body that specifies how the result will be calculated

To define our tripling function above in Haskell, we would write:

triple x = 3 * x

where triple is the function name, x is its only argument and3 * xis the function body. Notice that in Haskell, there is no need for parentheses that wrap around the arguments. The function name and the first argument, as well as any subsequent arguments, are simply separated by a space.

When the function is applied to actual arguments, the body of the function receives the arguments and the result is calculated (with curly parentheses signifying comments in the block below):

triple 4
= { applying triple }
3 * 4
= { applying * } 
12
PreviousIntroduction to HaskellNextFunctional Programming vs Imperative Programming

Last updated 2 years ago

Was this helpful?