2. Functions

Created Friday 22 August 2014

Calling a Function

sqrt 3
max 5 7
max (5 + 2) (sqrt 17)

Defining Functions

square x = x * x
GHCi> let square x = x * x
- - multiplies the largest of a and b by x
multMax a b x = (max a b) * x

if statement

posOrNeg x =
if x >= 0
then "Positive"
else "Negative"

Pure Functions

Pure Function Examples

Recursion

--pow2 n = 2 to the power n
pow2 n =
if n == 0
then 1 --the base case for the recursion
else 2 * (pow2 (n - 1))
In Java
int pow2(int n) {
int x = 1;
for (int i = 0; i < n; ++i)
x *= 2;
return x;
}
--repeats string n times
repeatString str n =
if n == 0
then ""
else str ++ (repeatString str (n-1))
In Java
int repeatString(String str, int n) {
String result = "";
for (int i = 0; i < n; ++i)
result += str;
return result;
}

Recursion Replaces Loops

Imitating loop
pow2 n = pow2loop n 1 0
pow2loop n x i =
if i < n
then pow2loop n (x * 2) (i + 1)
else x
n, x and i replace the equivalent variables in the Java loop:
int pow2(int n) {
int x = 1;
for (int i = 0; i < n; ++i)
x *= 2;
return x;
}

Lists

x = [1,2,3]
empty = []
y = 0 : x --[0,1,2,3] - prepend the list by 0, creates the new list, not modifies the x list
x' = 1 : (2 : (3 : [])) --the [...] notation is a shorthand for this 'colons' operator notation
x'' = 1 : 2 : 3 : [] --omitting the parentheses

Strings

Lists of characters
str = "abcde" --a shorthand for the following
str' = 'a' : 'b' : 'c' : 'd' : 'e' : []

Concatenating Lists

GHCi> [1,2,3] ++ [4,5]
GHCi> "hello" ++ " world"

Homogeneous Lists

Lists must contain only elements of the same type
error = [1,"hello",2]

Accessing Lists

head [1,2,3] --returns the 1st element
tail [1,2,3] --returns everything but the 1st element
head (tail [1,2,3]) --get the 2nd element

Testing for empty list

GHCi> null []
Result: True
GHCi> null [1,2]
Result: False

List Functions

double nums =
if null nums
then []
else (2 * (head nums)) : (double (tail nums))

removeOdd nums =
if null nums
then []
else
if (mod (head nums) 2) == 0 --even?
then (head nums) : (removeOdd (tail nums))
else removeOdd (tail nums)

Tuples

Provide a convenient way to package together a few values so that they can be passed around together.
x = (1, "hello")
y = ("pi", 3.14159, [1,2,3], "four")

Tuples vs Lists


Returning Tuples

headAndLength list = (head list, length list)

Accessing Tuple Elements

GHCi> fst (1, "hello")
Result: 1
GHCi> snd (1, "hello")
Result: "hello"

Pattern Matching

fst' (a,b) = a
snd' (a,b) = b

Pattern Matching Lists

null' [] = True --the null function returns True on empty list
null' (x : xs) = False --the null function returns False on the list with at least one element

head' (x : xs) = x
head' [] = error "head of empty list"

Using Pattern Matching

No pattern
double nums =
if null nums
then []
else (2 * (head nums)) : (double (tail nums))
Pattern
double [] = []
double (x : xs) = (2 * x) : (double xs)

Guards

The pattern matching looks only at a structure of data, guards can look at the values in the data
pow2 n
| n == 0 = 1
| otherwise = 2 * (pow2 (n - 1))
removeOdd without guards:
removeOdd nums =
if null nums
then []
else
if (mod (head nums) 2) == 0 --even?
then (head nums) : (removeOdd (tail nums))
else removeOdd (tail nums)
With guards
removeOdd [] = []
removeOdd (x : xs)
| mod x 2 == 0 = x : (removeOdd xs)
| otherwise = removeOdd xs

Case Expressions

double nums = case nums of
[] -> []
(x : xs) -> (2 * x) : (double xs)

anyEven nums = case (removeOdd nums) of
[] -> False
(x : xs) -> True

Guards forbidden in case expressions!

Let Binding

fancySeven =
let a = 3
in 2 * a + 1

fancyNine =
let x = 4
y = 5
in x + y

numEven nums =
let evenNums = removeOdd nums
in length evenNums

Where Binding

fancyNine = x + y
where x = 4
y = 5
where must be associated with function definition

Whitespace

fancyNine =
let x = 4
y = 5
in x + y

Lazy Function Evaluation

Lazy Infinite Lists

intsFrom n = n : (intsFrom (n + 1))
ints = intsFrom 1

GHCi> take 10 ints
GHCi> length ints --won't stop by itself
GHCi> let evenInts = removeOdd ints



Backlinks: