CHAPTER 1 - INTRODUCTION

PROGRAMMING IN HASKELL

What is a functional language?

Opinions differ, and it is difficult to give a precise definition, but generally speaking:

  • Functional programming is style of programming in which the basic method of computation is the application of functions to arguments.

  • A functional language is one that supports and encourages the functional style.

Example in Python:

Summing the integers 1 to 10 in Python

def sum(n):
    total = 0
    for i in range(n):
        total = total + i + 1
    return total

print(sum(10))

The computation method is variable assignment.

Example in Haskell:

Summing the integers 1 to 10 in Haskell:

In [3]:
sum [1..10]
55

The computation method is function application.

HISTORICAL BACKGROUND

1930s: Alonzo Church develops the lambda calculus, a simple but powerful theory of functions.

1950s: John McCarthy develops Lisp, the first functional language, with some influences from the lambda calculus, but retaining variable assignments.

1960s: Peter Landin develops ISWIM, the first pure functional language, based strongly on the lambda calculus, with no assignments.

1970s: John Backus develops FP, a functional language that emphasizes higher-order functions and reasoning about programs.

1970s: Robin Milner and others develop ML, the first modern functional language, which introduced type inference and polymorphic types.

1970s - 1980s: David Turner develops a number of lazy functional languages, culminating in the Miranda system.

1987: An international committee starts the development of Haskell, a standard lazy functional language.

1990s: Phil Wadler and others develop type classes and monads, two of the main innovations of Haskell.

2003: The committee publishes the Haskell Report, defining a stable version of the language; an updated version was published in 2010.

2010-date: Standard distribution, library support, new language features, development tools, use in industry, influence on other languages, etc.

A TASTE OF HASKELL

Example 1: double

In [4]:
double x = x + x
In [5]:
double 3
6
  double 3
= { applying double }
  3 + 3
= { applying + }
  6
In [6]:
double (double 3)
12
  double (double 3)
= { applying inner double }
  double (3 + 3)
= { applying + }
  double 6
= { applying double }
  6 + 6
= { applying + }
  12
  double (double 3)
= { applying outer double }
  double 3 + double 3
= { applying first double }
  (3 + 3) + double 3
= { applying first + }
  6 + double 3
= { applying double }
  6 + (3 + 3)
= { applying second + }
  6 + 6
= { applying + }
  12

Example 2 - sum

In [7]:
sum []     = 0
sum (n:ns) = n + sum ns
-- please ignore the following suggestion from Haskell on Jupyter Lab!!
Use foldr
Found:
sum [] = 0 sum (n : ns) = n + sum ns
Why Not:
sum ns = foldr (+) 0 ns
In [8]:
sum [1..10]
55
  sum [1..10]
= { applying [..] }
  sum [1,2,3,4,5,6,7,8,9,10]
= { applying sum }
  10 + (9 + (8 + (7 + (6 + (5 + (4 + (3 + (2 + (1 + 0)))))))))
= {applying + }
  55
In [9]:
:t sum
sum :: forall p. Num p => [p] -> p

Example 3 - ???

In [10]:
f []     = []
f (x:xs) = f ys ++ [x] ++ f zs
           where
              ys = [a | a <- xs, a <= x]
              zs = [b | b <- xs, b > x]

The above code is an example of ??? in HASKELL.

In [11]:
f [90,80,70,60,50,40,30,20,10]
[10,20,30,40,50,60,70,80,90]
  f [3,5,1,4,2]
= { applying f }
  f [1,2] ++ [3] ++ f [5,4]
= { applying both f's }
  (f [] ++ [1] ++ f [2]) ++ [3] ++ (f [4] ++ [5] ++ f [])
= { applying all f's }
  ([] ++ [1] ++ [] ++ [2] ++ f []) ++ [3] ++ ([] ++ [4] ++ f [] ++ [5] ++ [])
= { applying all f's }
  ([] ++ [1] ++ [] ++ [2] ++ []) ++ [3] ++ ([] ++ [4] ++ [] ++ [5] ++ [])
= { applying ++ within () }
  [1,2] ++ [3] ++ [4,5]
= { applying ++ }
  [1,2,3,4,5]
In [12]:
:t f
f :: forall a. Ord a => [a] -> [a]
In [13]:
f ["jones","adam","holly"]
["adam","holly","jones"]

Features of Haskell

  • Concise programs
  • Powerful type system
  • List comprehensions
  • Recursive functions
  • Higher-order functions
  • Effectful functions
  • Generic functions
  • Lazy evaluation
  • Equational reasoning