Purely functional Language

- Every Haskell funciton is pure

- Function will always yield the same output for the same argument

- No side effects


int n = 0;
int next_n() { 
    return n++; 
}

Side effects

Function is said to have a side effect if it modifies some state or has an observable interaction

Haskell

Referential transparency

Haskell


# referentially opaque
g = 0
def f1( x ):
    global g
    g = g + 1
    return g + x


# referentially transparent
def f2( x ):
    return x + 1

python> f1( 4 ) == f1( 4 )
False

python> f2( 4 ) == f2( 4 )
True

Strong static type  & Type inference

Haskell

Languages Strong/Weak Static/Dynamic
Java, C++, ML, Haskell Strong Static
Python Strong Dynamic
Javascript, PHP Weak Dynamic

Type System Comparison

Strong / Weak Typing

if ( true ) { 
    //do something 
}

if ( 'a' ) { 
    //do something 
} 

if ( 42 ) { 
    //do something 
}

JavaScript

if 'a' 
    then
        -- do something
    else
        -- do other thing

-- Error: Couldn't match expected type `Bool' with actual type `Char'

Haskell

Lazy evaluation (non-strict)

A code is executed only if its value is needed

Haskell can evaluate only a specific part of a very large data structure without loading the whole data into memory.

 

- lower memory footprint

- infinite data structure

Haskell

Tools

Haskell is both compiled and interpreted

 

Most commonly used tools:

Glasgow Haskell Compiler

GHC (Haskell Compiler)

GHCi (Haskell Interpreter)

Primitive Types

Int – bounded integer

Integer – unbounded integer

Float – real floating point with single precision

Double – real floating point with double precision

Bool – boolean type, True of False

Char – a character

Primitive Types

Integer – unbounded integer

 

factorial :: Integer -> Integer
factorial n = product [1..n]

λ> factorial 40
815915283247897734345611269596115894272000000000

Int– bounded integer

 

factorial :: Int -> Int
factorial n = product [1..n]

λ> factorial 40
-70609262346240000

Primitive Types

Float – real floating point with single precision

circumference :: Float -> Float
circumference r = 2 * pi * r

λ> circumference 5.0
31.415928

Double – real floating point with double precision

circumference :: Double -> Double
circumference r = 2 * pi * r

λ> circumference 5.0
31.41592653589793

Primitive Types

Bool – boolean type. True of False
 


λ> True && False  
False

λ> False || True  
True

λ> not False  
True

λ> True /= False
True

Boolean infix functions
 

Primitive Types

Char – a character is denoted by a single quotes.
String is a list of characters.

λ> :t ‘x’
‘x’ :: Char

λ> :t “hello”
“hello” :: [Char]

Lists

Lists are a homogeneous data structure which store elements of the same type. Lists are denoted by a square brackets and its value are separate by commas.


λ> let x = [1,2,3,4]
λ> x
[1,2,3,4]

Lists

Functions that operate on lists

λ> [1,2,3,4] !! 1
2

List indexing

List concatenation

λ> let x = [1,2,3]
λ> let y = [4,5,6]
λ> x ++ y
[1,2,3,4,5,6]

Cons operator (prepend)

λ> ‘A’ : “ Dog”
“A Dog”

Lists

Functions that operate on lists

λ> head [1,2,3,4]
1

head

tail

λ> tail [1,2,3,4]
[2,3,4]

length

λ> length [1,2,3,4]
4

null

λ> null []
True
λ> null [1,2,3,4]
False

Ranges

Ranges generate a lists that are arithmetic sequences of elements that can be enumerated.

 


λ> [1..10]
[1,2,3,4,5,6,7,8,9,10]

λ> [10,9..1]
[10,9,8,7,6,5,4,3,2,1]

Infinite list can be constructed by not specifying an upper limit.


λ> [1..]
[1,2,3,4..]

List comprehension

List comprehension is a syntactic construct for creating list based on existing lists. It follows the form of the mathematical set-builder notation (set comprehension)

 

S=\left \{ \ 2x \ |\ x\in \mathbb{N},\ x^2>3 \ \right \}
S={ 2x  xN, x2>3 }S=\left \{ \ 2x \ |\ x\in \mathbb{N},\ x^2>3 \ \right \}

This set comprehension can be written similarly as:


λ> [ 2*x | x <- [0..], x^2 > 3 ]
[4, 6, 8, 10, 12..]

python> [ 2*x for x in range( 10 ) if x**2 > 3 ]
[4, 6, 8, 10, 12, 14, 16, 18]

Tuples

Tuples are like lists except that it does not have to be homogeneous.

Tuples are denoted with parentheses and their components are separated by commas.


λ> fst (1, 2.5)
1

Functions that operate on two tuples

fst – a function that take a two tuples and returns the first component


λ> let x = (1, ‘a’, 2.3)
λ> x
(1, ‘a’, 2.3)

λ> snd (1, 2.5)
2.5

snd – a function that take a two tuples and returns the second component

Functions

Haskell function can be difined in two parts:
1. Optional function declaration
2. Function implementation

 


factorial :: Integer -> Integer
factorial 0 = 1
factorial n = n * factorial(n-1)

Pattern matching
Function can be defined with separate function bodies for different type of arguments. The type of argument that matches the pattern will fall through the corresponding function body.

Functions


factorial :: Integer -> Integer
factorial n
   | n == 0    = 1
   | n  > 0    = n * factorial (n-1)

Guards

Guards are similar to if else statement in imperative language. A guard determine a function body using a Boolean expression. If the expression evaluates to True, then the corresponding function body is used.

n!=\begin{Bmatrix} 1 & if\ n = 0\\ n(n-1)! & if\ n>0 \end{Bmatrix}
n!={1if n=0n(n1)!if n>0}n!=\begin{Bmatrix} 1 & if\ n = 0\\ n(n-1)! & if\ n>0 \end{Bmatrix}

Functions


absolute x
   | x < 0     = 0 – x
   | otherwise = x

Guards

The keyword otherwise can be use to catches everything. otherwise is simply defines as True.

Functions


collatzSum :: Integer -> Integer
collatzSum n
    | n < 0     = 0
    | n == 1    = 1
    | even n    = n + collatzSum (n `div` 2)
    | otherwise = n + collatzSum (3 * n + 1)

Java


public int collatzSum(int n) {
    if (n < 0) 
        return 0;
    else if (n == 1) 
        return 1;
    else if (n % 2 == 0) 
        return n + collatzSum(n / 2);
    else 
        return n + collatzSum(3 * n + 1);
}

Haskell

Functions

First-class Function

Haskell function is a first-class function. The language supports passing function as arguments to other functions, returning function as a values, assigning to a variable or storing in a data structures.

 

Haskell functions process one parameter at a time, using currying to support multiple arguments.

 

Calling a function with an incomplete argument resulting in a partially applied function.

Functions


map :: (a -> b) -> [a] -> [b]
map f []    = []
map f (h:t) = f h : map f t

Lambdas and Higher order functions


λ> map (\x -> x + 1) [1,2,3]
[2,3,4]

Functions


public <T> T first(T x, T y) {
    return x;
}

Generic functions


first :: a -> a -> a
first x y = x

Java

Haskell

(Parametric polymorphism)

Class


λ> :t (==)
(==) :: (Eq a) => a -> a -> Bool

A class is an interface that defines a behavior of a type.

- Not object oriented class.

- Provide a way to control overloading (ad-hoc polymorphism).

If a type is a member of a class that means it supports and implements the behavior of the class describes. 

Monad

[ x*2 | x <- [1..10], odd x ]

Monads is a function compositor.

Practical example: List Monad

List comprehension can be written using monads in different ways. 

do
   x <- [1..10]
   if odd x
      then [x*2]
      else []

do syntax allows programmer to program in the imperative style.

[1..10] >>= (\x -> if odd x the [x*2] else [])

bind operator (>>=)

Haskell

By nxxcxx

Haskell

Haskell programming language

  • 405