COMP313A Functional Programming (1)

143
1 COMP313A Functional Programming (1)

description

COMP313A Functional Programming (1). Main Differences with Imperative Languages. Say more about what is computed as opposed to how Pure functional languages have no variables assignments other side effects Means no loops. Differences…. - PowerPoint PPT Presentation

Transcript of COMP313A Functional Programming (1)

Page 1: COMP313A Functional Programming (1)

1

COMP313AFunctional

Programming (1)

Page 2: COMP313A Functional Programming (1)

2

Main Differences with Imperative Languages

• Say more about what is computed as opposed to how

• Pure functional languages have no – variables– assignments – other side effects

• Means no loops

Page 3: COMP313A Functional Programming (1)

3

Differences…

• Imperative languages have an implicit state (state of variables) that is modified (side effect).

• Sequencing is important to gain precise, deterministic control over the state

• assignment statement needed to change the binding for a particular variable (alter the implicit state)

Page 4: COMP313A Functional Programming (1)

4

• Imperative factorial

n:=x;a:=1;while n > 0 dobegin

a:= a * n;n := n-1;

end;

Page 5: COMP313A Functional Programming (1)

5

Differences

• Declarative languages have no implicit state

• Program with expressions• The state is carried around explicitly

– e.g. the formal parameter n in factorial

• Looping is accomplished with recursion rather than sequencing

Page 6: COMP313A Functional Programming (1)

6

Haskellfac ::Int -> Intfac n | n == 0 = 1 | n > 0 = fac(n-1) *

n | otherwise = 0

Scheme (define fac (lambda (n) (if (= n 0) 1 (* n (fac (- n 1))))))

Page 7: COMP313A Functional Programming (1)

7

Advantages

• similar to traditional mathematics• referential transparency makes

programs more readable• higher order functions give great

flexibility• concise programs

Page 8: COMP313A Functional Programming (1)

8

Referential Transparency

• the value of a function depends only on the values of its parameters

for example Haskell

…x + x…where x = f a

Page 9: COMP313A Functional Programming (1)

9

Evolution of Functional languages

Lambda Calculus• Alonzo Church• Captures the essence of functional

programming• Formalism for expressing computation by

functions• Lambda abstraction

• In Scheme

• In Haskell

(x. + 1 x)

(lambda(x) (+ 1 x)))

add1 :: Int -> Intadd1 x = 1 + x

Page 10: COMP313A Functional Programming (1)

10

Lambda Calculus…

• application of expressions

• reduction rule that substitutes 2 for x in the lambda (beta reduction)

(x. + 1 x) 2

(x. + 1 x) 2 (+ 1 2) 3

(x. * x x) (+ 2 3) i.e. (+ 2 3) / x)

Page 11: COMP313A Functional Programming (1)

11

Lambda Calculus…

• (x.E) – variable x is bound by the lambda– the scope of the binding is the expression E

• (x. + y x)– (x. + y x)2 (+ y 2)

• (x. + ((y. ((x. * x y) 2)) x) y)

Page 12: COMP313A Functional Programming (1)

12

Lambda Calculus…

• Each lambda abstraction binds only one variable

• Need to bind each variable with its own lambda.

(x. (y. + x y))

Page 13: COMP313A Functional Programming (1)

13

Lisp

• McCarthy late 1950s• Used Lambda Calculus for

anonymous functions• List processing language• First attempt built on top of FORTRAN

Page 14: COMP313A Functional Programming (1)

14

LISP…• McCarthy’s main contributions were

1. the conditional expression and its use in writing recursive functions

Scheme (define fac (lambda (n) (if (= n 0) 1 (if (> n 0) (* n (fac (- n 1))) 0))))

Scheme(define fac2 (lambda (n) (cond ((= n 0) 1) ((> n 0) (* n (fac2 (- n 1)))) (else 0))))

Haskellfac ::Int -> Intfac n | n == 0 = 1 | n > 0 = fac(n-1) * n | otherwise = 0

Haskellfac :: Int -> Intfac n = if n == 0 then 1 else if n > 0 then fac(n-1) * n else 0

Page 15: COMP313A Functional Programming (1)

15

2.the use of lists and higher order operations over lists such as mapcar

Lisp…

Scheme(mymap + ’(3 4 6) ’(5 7 8))

Haskellmymap :: (Int -> Int-> Int) -> [Int] -> [Int] ->[Int]mymap f [] [] = []mymap f (x:xs) (y:ys) = f x y : mymap f xs ys

add :: Int -> Int -> Intadd x y = x + y

Scheme(define mymap (lambda (f a b) (cond ((and (null? a) (null? b)) '()) (else (cons (f (first a) (first b)) (mymap f (rest a) (rest b)))))))

Haskellmymap add [3, 4, 6] [5, 7, 8]

Page 16: COMP313A Functional Programming (1)

16

Lisp

3. cons cell and garbage collection of unused cons cells

Scheme (cons ’1 ’(3 4 5 7))

(1 3 4 5 7)

Haskellcons :: Int -> [Int] -> [Int]cons x xs = x:xs

Scheme(define mymap (lambda (f a b) (cond ((and (null? a) (null? b)) '()) (else (cons (f (first a) (first b)) (mymap f (first a) (first b)))))))

Page 17: COMP313A Functional Programming (1)

17

Lisp…

4. use of S-expressions to represent both program and data

An expression is an atom or a listBut a list can hold anything…

Page 18: COMP313A Functional Programming (1)

18

Scheme (cons ’1 ’(3 4 5 7))

(1 3 4 5 7)

Scheme(define mymap (lambda (f a b) (cond ((and (null? a) (null? b)) '()) (else (cons (f (first a) (first b)) (mymap f (first a) (first b)))))))

Page 19: COMP313A Functional Programming (1)

19

ISWIM

• Peter Landin – mid 1960s• If You See What I Mean

Landon wrote “…can be looked upon as an attempt to deliver Lisp from its eponymous commitment to lists, its reputation for hand-to-mouth storage allocation, the hardware dependent flavour of its pedagogy, its heavy bracketing, and its compromises with tradition”

Page 20: COMP313A Functional Programming (1)

20

Iswim…

• Contributions– Infix syntax– let and where clauses, including a notion of

simultaneous and mutually recursive definitions

– the off side rule based on indentation• layout used to specify beginning and end of

definitions

– Emphasis on generality • small but expressive core language

Page 21: COMP313A Functional Programming (1)

21

let in Scheme

• let* - the bindings are performed sequentially

(let* ((x 2) (y 3))

(* x y))

(let* ((x 2) (y 3))

(let* ((x 7) (z (+ x y)))

(* z x)))

Page 22: COMP313A Functional Programming (1)

22

let in Scheme

(let ((x 2) (y 3)) ?

(* x y))

• let - the bindings are performed in parallel, i.e. the initial values are computed before any of the variables are bound

(let ((x 2) (y 3)) (let ((x 7) (z (+ x y))) ?

(* z x)))

Page 23: COMP313A Functional Programming (1)

23

letrec in Scheme

• letrec – all the bindings are in effect while their initial values are being computed, allows mutually recursive definitions

(letrec ((even? (lambda (n) (if (zero? n) #t (odd? (- n 1))))) (odd? (lambda (n) (if (zero? n) #f (even? (- n 1)))))) (even? 88))

Page 24: COMP313A Functional Programming (1)

24

ML

• Gordon et al 1979• Served as the command language for a proof

generating system called LCF– LCF reasoned about recursive functions

• Comprised a deductive calculus and an interactive programming language – Meta Language (ML)

• Has notion of references much like locations in memory

• I/O – side effects• But encourages functional style of programming

Page 25: COMP313A Functional Programming (1)

25

ML

• Type System– it is strongly and statically typed– uses type inference to determine the type of

every expression– allows polymorphic functions

• Has user defined ADTs

Page 26: COMP313A Functional Programming (1)

26

SASL, KRC, and Miranda

• Used guards • Higher Order Functions• Lazy Evaluation• Currying

SASLfac n = 1, n = 0 = n * fac (n-1), n>0

Haskellfac n | n ==0 = 1 | n >0 = n * ( fac(n-1)

add x y = + x y

add 1

switch :: Int -> a -> a -> aswitch n x y| n > 0 = x| otherwise = y

multiplyC :: Int -> Int -> IntVersusmultiplyUC :: (Int, Int) -> Int

Page 27: COMP313A Functional Programming (1)

27

SASL, KRC and Miranda

• KRC introduced list comprehension

• Miranda borrowed strong data typing and user defined ADTs from ML

comprehension :: [Int] -> [Int]comprehension ex = [2 * n | n <- ex]

Page 28: COMP313A Functional Programming (1)

28

COMP313AFunctional

Programming (1)

Page 29: COMP313A Functional Programming (1)

29

LISP…• McCarthy’s main contributions were

1. the conditional expression and its use in writing recursive functions

Scheme (define fac (lambda (n) (if (= n 0) 1 (if (> n 0) (* n (fac (- n 1))) 0))))

Scheme(define fac2 (lambda (n) (cond ((= n 0) 1) ((> n 0) (* n (fac2 (- n 1)))) (else 0))))

Haskellfac ::Int -> Intfac n | n == 0 = 1 | n > 0 = fac(n-1) * n | otherwise = 0

Haskellfac :: Int -> Intfac n = if n == 0 then 1 else if n > 0 then fac(n-1) * n else 0

Page 30: COMP313A Functional Programming (1)

30

2.the use of lists and higher order operations over lists such as mapcar

Lisp…

Scheme(mymap + ’(3 4 6) ’(5 7 8))

Haskellmymap :: (Int -> Int-> Int) -> [Int] -> [Int] ->[Int]mymap f [] [] = []mymap f (x:xs) (y:ys) = f x y : mymap f xs ys

add :: Int -> Int -> Intadd x y = x + y

Scheme(define mymap (lambda (f a b) (cond ((and (null? a) (null? b)) '()) (else (cons (f (first a) (first b)) (mymap f (rest a) (rest b)))))))

Haskellmymap add [3, 4, 6] [5, 7, 8]

Page 31: COMP313A Functional Programming (1)

31

Lisp

3. cons cell and garbage collection of unused cons cells

Scheme (cons ’1 ’(3 4 5 7))

(1 3 4 5 7)

Haskellcons :: Int -> [Int] -> [Int]cons x xs = x:xs

Scheme(define mymap (lambda (f a b) (cond ((and (null? a) (null? b)) '()) (else (cons (f (first a) (first b)) (mymap f (first a) (first b)))))))

Page 32: COMP313A Functional Programming (1)

32

Lisp…

4. use of S-expressions to represent both program and data

An expression is an atom or a listBut a list can hold anything…

Page 33: COMP313A Functional Programming (1)

33

Scheme (cons ’1 ’(3 4 5 7))

(1 3 4 5 7)

Scheme(define mymap (lambda (f a b) (cond ((and (null? a) (null? b)) '()) (else (cons (f (first a) (first b)) (mymap f (first a) (first b)))))))

Page 34: COMP313A Functional Programming (1)

34

ISWIM

• Peter Landin – mid 1960s• If You See What I Mean

Landon wrote “…can be looked upon as an attempt to deliver Lisp from its eponymous commitment to lists, its reputation for hand-to-mouth storage allocation, the hardware dependent flavour of its pedagogy, its heavy bracketing, and its compromises with tradition”

Page 35: COMP313A Functional Programming (1)

35

Iswim…

• Contributions– Infix syntax– let and where clauses, including a notion of

simultaneous and mutually recursive definitions

– the off side rule based on indentation• layout used to specify beginning and end of

definitions

– Emphasis on generality • small but expressive core language

Page 36: COMP313A Functional Programming (1)

36

let in Scheme

• let* - the bindings are performed sequentially

(let* ((x 2) (y 3))

(* x y))

(let* ((x 2) (y 3))

(let* ((x 7) (z (+ x y)))

(* z x)))

Page 37: COMP313A Functional Programming (1)

37

let in Scheme

(let ((x 2) (y 3)) ?

(* x y))

• let - the bindings are performed in parallel, i.e. the initial values are computed before any of the variables are bound

(let ((x 2) (y 3)) (let ((x 7) (z (+ x y))) ?

(* z x)))

Page 38: COMP313A Functional Programming (1)

38

letrec in Scheme

• letrec – all the bindings are in effect while their initial values are being computed, allows mutually recursive definitions

(letrec ((even? (lambda (n) (if (zero? n) #t (odd? (- n 1))))) (odd? (lambda (n) (if (zero? n) #f (even? (- n 1)))))) (even? 88))

Page 39: COMP313A Functional Programming (1)

39

• Emacs was/is written in LISP

• Very popular in AI research

Page 40: COMP313A Functional Programming (1)

40

ML

• Gordon et al 1979• Served as the command language for a proof

generating system called LCF– LCF reasoned about recursive functions

• Comprised a deductive calculus and an interactive programming language – Meta Language (ML)

• Has notion of references much like locations in memory

• I/O – side effects• But encourages functional style of programming

Page 41: COMP313A Functional Programming (1)

41

ML

• Type System– it is strongly and statically typed– uses type inference to determine the type of

every expression– allows polymorphic functions

• Has user defined ADTs

Page 42: COMP313A Functional Programming (1)

42

SASL, KRC, and Miranda

• Used guards • Higher Order Functions• Lazy Evaluation• Currying

SASLfac n = 1, n = 0 = n * fac (n-1), n>0

Haskellfac n | n ==0 = 1 | n >0 = n * fac(n-1)

add x y = + x y

silly_add x y = x

add 4 (3 * a)

switch :: Int -> a -> a -> aswitch n x y| n > 0 = x| otherwise = y

multiplyC :: Int -> Int -> Int VersusmultiplyUC :: (Int, Int) -> Int

Page 43: COMP313A Functional Programming (1)

43

SASL, KRC and Miranda

• KRC introduced list comprehension

• Miranda borrowed strong data typing and user defined ADTs from ML

comp_example :: [Int] -> [Int]comp_example ex = [2 * n | n <- ex]

Page 44: COMP313A Functional Programming (1)

44

The Move to Haskell

• Lots of functional languages in late 1970’s and 1980’s

• Tower of Babel• Among these was Hope

– strongly typed– polymorphism but explicit type declarations

as part of all function definitions– simple module facility– user-defined concrete data types with

pattern matching

Page 45: COMP313A Functional Programming (1)

45

The Move to Haskell

• 1987 – considered lack of common language was hampering the adoption of functional languages

• Haskell was born– higher order functions– lazy evaluation– static polymorphic typing– user-defined datatypes– pattern matching– list comprehensions

Page 46: COMP313A Functional Programming (1)

46

Haskell…

• as well– module facility– well defined I/O system– rich set of primitive data types

Page 47: COMP313A Functional Programming (1)

47

Higher Order Functions

• Functions as first class values– stored as data structures, passed as

arguments, returned as results

• Function is the primary abstraction mechanism– increase the use of this abstraction

• Higher order functions are the “guts” of functional programming

Page 48: COMP313A Functional Programming (1)

48

Higher Order FunctionsComputations over lists

• Mapping– add 5 to every element of a list. – add the corresponding elements of 2 lists

• Filtering– Selecting the elements with a certain property

• Folding – Combine the items in a list in some way

Page 49: COMP313A Functional Programming (1)

49

List Comprehension

Double all the elements in a list

Using primitive recursiondoubleAll :: [Int] -> [Int]doubleAll [] = []doubleAll x:xs = 2 * x : doubleAll xs

Using list comprehensiondoubleAll :: [Int] -> [Int]doubleAll xs :: [ 2 * x | x <- xs ]

Page 50: COMP313A Functional Programming (1)

50

Primitive Recursionversus

General Recursion

sum :: [Int] -> Intsum [] = 0sum (x:xs) = x + sum xs

qsort :: [Int] -> [Int]qsort [] = []qsort (x : xs) = qsort [ y | y<-xs , y<=x] ++ [x] ++ qsort [ y | y <- xs ,

y>x]

Page 51: COMP313A Functional Programming (1)

51

COMP313AFunctional

Programming (3)

Page 52: COMP313A Functional Programming (1)

52

Higher Order Functions

• Functions as first class values– stored as data structures, passed as

arguments, returned as results

• Function is the primary abstraction mechanism– increase the use of this abstraction

• Higher order functions are the “guts” of functional programming

Page 53: COMP313A Functional Programming (1)

53

Higher Order FunctionsComputations over lists

• Mapping– add 5 to every element of a list. – add the corresponding elements of 2 lists

• Filtering– Selecting the elements with a certain property

• Folding – Combine the items in a list in some way

Page 54: COMP313A Functional Programming (1)

54

List Comprehension

Double all the elements in a list

Using primitive recursiondoubleAll :: [Int] -> [Int]doubleAll [] = []doubleAll x:xs = 2 * x : doubleAll xs

Using list comprehensiondoubleAll :: [Int] -> [Int]doubleAll xs = [ 2 * x | x <- xs ]

Page 55: COMP313A Functional Programming (1)

55

Primitive Recursionversus

General Recursion

sum :: [Int] -> Intsum [] = 0sum (x:xs) = x + sum xs

qsort :: [Int] -> [Int]qsort [] = []qsort (x : xs) = qsort [ y | y<-xs , y<=x] ++ [x] ++ qsort [ y | y <- xs ,

y>x]

Page 56: COMP313A Functional Programming (1)

56

Some Haskell Syntax

Write a function to calculate the maximum of three numbers

i.e. maxThree :: Int -> Int -> Int

maxThree x y z | x >= y && x >= z = x | y >= z = y | otherwise = z

Page 57: COMP313A Functional Programming (1)

57

Write a function to calculate the average of three numbers

averageThree :: Int-> Int -> Int -> Float

averageThree x y z = (x + y + z) / 3

funny x = x + x peculiar y = y

funny x = x + xpeculiar y = y

Page 58: COMP313A Functional Programming (1)

58

Tuples and Lists

Examples of lists

[345, 67, 34, 9] [‘a’, ‘h’, ‘z’] [“Fred”, “foo”]

Examples of tuples

(“Fred”, 471) (“apples”, 3.41) (“baseball_bat”, “aluminium” 60.0)

Strings are lists of char i.e. [Char]

[‘f’, ‘r’, ‘e’, ‘d’] = “fred”

Page 59: COMP313A Functional Programming (1)

59

Types

type album = (String, String, Int)

type collection = [album]

Page 60: COMP313A Functional Programming (1)

60

Some more examplespattern matching

Write a function which will extract all the even numbers from a list

Lets first create an isEven predicate

isEven n = (n ‘mod’ 2 == 0)

evenList [] = []evenList ex = [n | n <- ex , isEven n]

evenList2 [] = []evenList2 (x:xs) |isEven x = x : evenList2 xs |otherwise = evenList2 xs

Page 61: COMP313A Functional Programming (1)

61

Write a function listpairs which returns a list of the pairsof corresponding elements in two lists

listpairs :: [a] -> [b] -> [(a,b)]

>>listpairs [3, 4, 5] [6, 7, 8]>> [(3,6), (4, 7), (5,8)]

Would this work?

listpairs xs ys = [(m,n) | m <- xs, n <- ys]

Page 62: COMP313A Functional Programming (1)

62

COMP313AFunctional

Programming (4)

Page 63: COMP313A Functional Programming (1)

63

Lecture Outline

• A little bit of revision• Higher Order Functions

– Functions as arguments– Functions as values

Page 64: COMP313A Functional Programming (1)

64

Some more examplespattern matching

Write a function which will extract all the even numbers from a list

Lets first create an isEven predicate

isEven n = (mod n 2 == 0)

evenList [] = []evenList ex = [n | n <- ex , isEven n]

evenList2 [] = []evenList2 (x:xs) |isEven x = x : evenList2 xs |otherwise = evenList2 xs

Page 65: COMP313A Functional Programming (1)

65

List Comprehension

Given a function isDigit

isDigit :: Char -> Bool

which returns True if a character is a digit, write a function digits which will find all the digits in a string

digits str = [ aChar | aChar <- , ]

Page 66: COMP313A Functional Programming (1)

66

Map

double x = 2 * x

doubleAll xs = map double xs

doubleAll [4, 5, 6] [8, 10, 12]

Page 67: COMP313A Functional Programming (1)

67

Implementing Map using List Comprehension

map :: (a -> b) -> [a] -> [b]

map f xs = [ f x | x <- xs ]

Page 68: COMP313A Functional Programming (1)

68

Functions as Argumentsfold

> foldr1 (+) [4, 5, 6]> 15

Page 69: COMP313A Functional Programming (1)

69

foldr1 (non empty list)

foldr1 :: (a -> a -> a) -> [a] -> afoldr1 f [x] = xfoldr1 f (x:xs) = f x (foldr f xs)

What does this tell us abut the characteristics of function “f”

Produces an error when given an empty list How could we define foldr to work with an empty list

Page 70: COMP313A Functional Programming (1)

70

foldr f s [] = sfoldr f s (x:xs) = f x (foldr f s xs)

Page 71: COMP313A Functional Programming (1)

71

1 More Higher Order FunctionFilter

isEven n = (mod n 2 == 0)

> filter isEven [2, 4, 6, 7, 1]>??

isEven returns a predicate (returns a Bool)

Page 72: COMP313A Functional Programming (1)

72

Implementing Filter using list comprehension

filter p xs = [x | x <- xs, p x]

p returns a Bool

Page 73: COMP313A Functional Programming (1)

73

Some exercises

• Write functions to

(1)Return the list consisting of the squares of the integers in a list, ns.

(2)Return the sum of squares of items in a list

(3)Check whether all the items of a list are greater than zero using filter

Page 74: COMP313A Functional Programming (1)

74

Functions as values

• functions as data• function composition

sqr (succ 5) concat (map bracketedWithoutVowels xs)

concatenates a list of lists into a single list flattens a list

Page 75: COMP313A Functional Programming (1)

75

Functions as valuesFunction Composition (.)

(sqr . succ) 5• The output of one function becomes the input of

another

g f

f.ga a b c c

(.) :: (b -> c) -> (a ->b) -> (a -> c)

type of f type of g type of (f.g)

Page 76: COMP313A Functional Programming (1)

76

f . g x as opposed to (f . g) x

Function application binds more tightly than composition

e.g not . not True

or

succ .pred 5

Page 77: COMP313A Functional Programming (1)

77

Functions as values and results

twice fun = ( fun . fun )

• fun is a function • The result is fun composed with itself

For this to work fun has to have …..and twice :: ( ) -> ( )

> twice succ 2 > 4

Page 78: COMP313A Functional Programming (1)

78

Expressions Defining Functions

addnum :: Int -> (Int -> Int)addnum n = addN where addN m = n + m

When addnum 10 say is called returns a function addN which adds 10 to m

Page 79: COMP313A Functional Programming (1)

79

Main> addNum 4 59

Main> addNum 4

ERROR - Cannot find "show" function for:*** Expression : addNum 4*** Of type : Integer -> Integer

Page 80: COMP313A Functional Programming (1)

80

test :: Int -> Int -> Int

test x y | x >= y = f y | otherwise = 4 where f = addnum 4

Page 81: COMP313A Functional Programming (1)

81

COMP313AFunctional

Programming (4)

Page 82: COMP313A Functional Programming (1)

82

Lecture Outline

• A little bit of revision• Higher Order Functions

– Functions as arguments– Functions as values

Page 83: COMP313A Functional Programming (1)

83

Some more examplespattern matching

Write a function which will extract all the even numbers from a list

Lets first create an isEven predicate

isEven n = (mod n 2 == 0)

evenList [] = []evenList ex = [n | n <- ex , isEven n]

evenList2 [] = []evenList2 (x:xs) |isEven x = x : evenList2 xs |otherwise = evenList2 xs

Page 84: COMP313A Functional Programming (1)

84

List Comprehension

Given a function isDigit

isDigit :: Char -> Bool

which returns True if a character is a digit, write a function digits which will find all the digits in a string

digits str = [ aChar | aChar <- , ]

Page 85: COMP313A Functional Programming (1)

85

Map

double x = 2 * x

doubleAll xs = map double xs

doubleAll [4, 5, 6] [8, 10, 12]

Page 86: COMP313A Functional Programming (1)

86

Implementing Map using List Comprehension

map :: (a -> b) -> [a] -> [b]

map f xs = [ f x | x <- xs ]

Page 87: COMP313A Functional Programming (1)

87

Functions as Argumentsfold

> foldr1 (+) [4, 5, 6]> 15

Page 88: COMP313A Functional Programming (1)

88

foldr1 (non empty list)

foldr1 :: (a -> a -> a) -> [a] -> afoldr1 f [x] = xfoldr1 f (x:xs) = f x (foldr f xs)

What does this tell us abut the characteristics of function “f”

Produces an error when given an empty list How could we define foldr to work with an empty list

Page 89: COMP313A Functional Programming (1)

89

foldr f s [] = sfoldr f s (x:xs) = f x (foldr f s xs)

Page 90: COMP313A Functional Programming (1)

90

1 More Higher Order FunctionFilter

isEven n = (mod n 2 == 0)

> filter isEven [2, 4, 6, 7, 1]>??

isEven returns a predicate (returns a Bool)

Page 91: COMP313A Functional Programming (1)

91

Implementing Filter using list comprehension

filter p xs = [x | x <- xs, p x]

p returns a Bool

Page 92: COMP313A Functional Programming (1)

92

Some exercises

• Write functions to

(1)Return the list consisting of the squares of the integers in a list, ns.

(2)Return the sum of squares of items in a list

(3)Check whether all the items of a list are greater than zero using filter

Page 93: COMP313A Functional Programming (1)

93

Functions as values

• functions as data• function composition

sqr (succ 5) concat (map bracketedWithoutVowels xs)

concatenates a list of lists into a single list flattens a list

Page 94: COMP313A Functional Programming (1)

94

Functions as valuesFunction Composition (.)

(sqr . succ) 5• The output of one function becomes the input of

another

g f

f.ga a b c c

(.) :: (b -> c) -> (a ->b) -> (a -> c)

type of f type of g type of (f.g)

Page 95: COMP313A Functional Programming (1)

95

f . g x as opposed to (f . g) x

Function application binds more tightly than composition

e.g not . not True

or

succ .pred 5

Page 96: COMP313A Functional Programming (1)

96

Functions as values and results

twice fun = ( fun . fun )

• fun is a function • The result is fun composed with itself

For this to work fun has to have …..and twice :: ( ) -> ( )

> twice succ 2 > 4

Page 97: COMP313A Functional Programming (1)

97

Expressions Defining Functions

addnum :: Int -> (Int -> Int)addnum n = addN where addN m = n + m

When addnum 10 say is called returns a function addN which adds 10 to m

Page 98: COMP313A Functional Programming (1)

98

Main> addNum 4 59

Main> addNum 4

ERROR - Cannot find "show" function for:*** Expression : addNum 4*** Of type : Integer -> Integer

Page 99: COMP313A Functional Programming (1)

99

test :: Int -> Int -> Int

test x y | x >= y = f y | otherwise = 4 where f = addnum 4

Page 100: COMP313A Functional Programming (1)

100

COMP313A Programming Languages

Functional Programming (5)

Page 101: COMP313A Functional Programming (1)

101

Lecture Outline

• Higher order functions• Functions as arguments• Some recapping and

exercises• Some more functions as

data and results

Page 102: COMP313A Functional Programming (1)

102

Expressions Defining Functions

addnum :: Int -> (Int -> Int)addnum n = addN where -- local definition addN m = n + m

When addnum 10 say is called returns a function addN which adds 10 to m

Page 103: COMP313A Functional Programming (1)

103

test :: Int -> Int -> Inttest x y | x >= y = somefun f y | otherwise = 4 where f = addnum 4

Page 104: COMP313A Functional Programming (1)

104

Lambda in Haskell

\m -> n + m

addNum n = (\m -> n + m)

Write a function “test n” that returns a function which tests if some argument is <= to n. Use a lambda.

Page 105: COMP313A Functional Programming (1)

105

Partial Application of Functions

add :: Int -> Int -> Intadd x y = x+y 4

5

4

Page 106: COMP313A Functional Programming (1)

106

Partial Application of Functions…

add4 :: [Int] -> [Int]add4 xs = map (add 4) xs

add4 :: ([Int] -> [Int])add4 = map (add 4)

How would we use partial applications of functions to get the same result as the “addNum n” example?

Page 107: COMP313A Functional Programming (1)

107

Types of partial applications

The type of function is t1 -> t2 -> … tn -> t

and it is applied to arguments

e1 :: t1, e2 :: t2 … , ek :: tk

if k <= n (partial application) then cancel the ones that match t1 – tk

leaving

tk+1 -> tk+2 -> … -> tn

Page 108: COMP313A Functional Programming (1)

108

Types of Partial Function Application

add :: Int -> Int -> Int

add 2 :: Int ->Intadd 2 3 :: Int

Page 109: COMP313A Functional Programming (1)

109

Operator Sections

(*2) (2*)(>2) (6:) (\2)

filter (>0) . map (+1) Find operator sections sec1 and sec2 so thatmap sec1. filter sec2 Has the same effect as filter (>0) . map (+1)

Page 110: COMP313A Functional Programming (1)

110

Partial Application of Functionsand

Operator Sections

elem :: Char -> [Char] -> Bool

elem ch whitespace

where whitespace is the string “ \t\n”

Page 111: COMP313A Functional Programming (1)

111

Partial Application of Functionsand Operator Sections

i.e. whitespace = “ \t\n”

The problem with partial application of function is that the argument of interest may not always be the first argument

So

member xs x = elem x xs

and

member whitespace

Alternatively we can use a lambda function\ch -> elem ch whitespace

Page 112: COMP313A Functional Programming (1)

112

Partial Application of Functionsand

Operator Sections

To filter all non-whitespace characters from a string

filter (not . member whitespace)

filter (\ch -> not (elem ch whitespace))

Page 113: COMP313A Functional Programming (1)

113

Write a recursive function to extract a word from a string

whitespace = “ \n\t”

getword :: String -> Stringgetword [ ] = [ ]getword (x : xs) | --how do we know we have a word | -- otherwise build the word - - recursively

getword “the quick brown”

Page 114: COMP313A Functional Programming (1)

114

Write a recursive function to extract a word from a string

Can write something more general - pass the “test” as an argument

getUntil :: (a -> Bool) -> [a] -> [a]getUntil p [ ] = [ ]getUntil p (x:xs) | p x = [ ] | otherwise = x : getUntil p xs

Page 115: COMP313A Functional Programming (1)

115

Write a recursive function to extract a word from a string

Okay but now how do we get a word

getWord xs = getUntil p xs where - - local definition p x = member whitespace x

Page 116: COMP313A Functional Programming (1)

116

Write a recursive function to extract a word from a string

But we don’t really need the local definition

We can use our partial function instead

getWord xs = getUntil p xs where - - local definition p x = member whitespace x

getWord xs = getUntil (member whitespace) xs

Page 117: COMP313A Functional Programming (1)

117

Write a recursive function to extract a word from a string

Finally

The last word

getWord = getUntil (member whitespace)

---get characters until a whitespace is found

Page 118: COMP313A Functional Programming (1)

118

Currying and Uncurrying

• functions of two or more arguments take arguments in sequence, one at a time.– this is the curried form. – named after Haskell Curry

• Uncurried version puts the arguments into a pair

addUC :: (Int, Int) -> Int addUC (x,y) = (x + y)

Page 119: COMP313A Functional Programming (1)

119

curried versus uncurried

• Curried has neater notation• Curried permits partial application• Can easily convert from one to the other

curry f (x y) = f x y

uncurry f x y = f (x y)

Page 120: COMP313A Functional Programming (1)

120

Type Checking in HaskellMonomorphic Type Checking

• Expressionsliteral, variable, constant, function applied to some arguments

• type checking function application– what do we need to consider

Page 121: COMP313A Functional Programming (1)

121

f e

e must have type s

the result has type t

f must have a function type t

Page 122: COMP313A Functional Programming (1)

122

ord ‘c’ +Int 3Int

ord ‘c’ +Int False

Page 123: COMP313A Functional Programming (1)

123

Type Checking Function Definitions

fib :: Int ->Intfib n | n == 0 = 0 | n == 1 = 1 | n >1 = fib (n-2) + fib (n-1)

•Each of the guards must be of type ?

•The value returned in each clause must be of type ?

•The pattern n must be consistent with type argument ?

Page 124: COMP313A Functional Programming (1)

124

COMP313A Programming Languages

Logic Programming (1)

Page 125: COMP313A Functional Programming (1)

125

Lecture Outline

• Conceptual foundations of Logic Programming

• The Basics of Logic Programming– Predicate Calculus

• A little bit of logic programming– Prolog

Page 126: COMP313A Functional Programming (1)

126

Conceptual Foundations

• What versus how– specification versus implementation

• Declarative Programming– Programmer declares the logical properties that

describe the property to be solved– From this a solution is inferred– Inference engine

Page 127: COMP313A Functional Programming (1)

127

An example

Searching for an element in a listSearching for an element in a list

Predicate is_in(x,L) true whenever element x is in the list Predicate is_in(x,L) true whenever element x is in the list L.L.

For all elements x and lists L: is_in(x,L) For all elements x and lists L: is_in(x,L) IFFIFF

L = [x]L = [x] oror L = L1 L = L1 .. L2 and L2 and (is_in (x,L1) or is_in(x, L2))(is_in (x,L1) or is_in(x, L2))

Page 128: COMP313A Functional Programming (1)

128

Example continuedImplementation

• Need to know how to split a list into right and left sublists

• How to order the elements stored in the list

Page 129: COMP313A Functional Programming (1)

129

A solution in C++int binary_search(const int val, const int size, const int int binary_search(const int val, const int size, const int array[]){array[]){int high, low, mid;int high, low, mid;if size <= 0{if size <= 0{ return (-1);return (-1);}}high = size; high = size; low = 0;low = 0;for(;;) {for(;;) { mid = (high + low) / 2;mid = (high + low) / 2; if (mid = low){if (mid = low){ return (val != array[low]) ?-1:mid;return (val != array[low]) ?-1:mid;}}if (val < array[mid]) {if (val < array[mid]) { high = mid;high = mid;}}else if (val > array[mid]) {else if (val > array[mid]) { low = mid;low = mid;}}else return midelse return mid}}}}}}

Page 130: COMP313A Functional Programming (1)

130

A Declarative Solution

Given an element x and a list L, to prove that x is in L, Given an element x and a list L, to prove that x is in L, proceed as follows: proceed as follows: (1)(1) Prove that L is [x]Prove that L is [x]

(2)(2) Otherwise split L into L1 Otherwise split L into L1 .. L2 and prove one of the following L2 and prove one of the following(2.1) x is in L1, or(2.1) x is in L1, or(2.2) x is in L2(2.2) x is in L2

Page 131: COMP313A Functional Programming (1)

131

A sorting example

A predicate A predicate sort(X,Y)sort(X,Y)

Sort(X,Y) Sort(X,Y) is true if the nonempty list Y is the sorted is true if the nonempty list Y is the sorted version of Xversion of X

Use two auxiliary predicates: permutation(X,Y) and Use two auxiliary predicates: permutation(X,Y) and is_sorted(Y)is_sorted(Y)

For all integer lists X,Y: sort(X,Y) iffFor all integer lists X,Y: sort(X,Y) iff permutation(X,Y) and sorted(Y)permutation(X,Y) and sorted(Y)

Page 132: COMP313A Functional Programming (1)

132

Logic and Logic Programming

• First-order predicate calculus– Logic statements

ExamplesJohn is a man. man(John).John is a human. human(John).Tristan is the son of Margaret. son(Margaret,Tristan).A horse is a mammal. loathes(Margaret, Heavy_Metal).0 is a natural number . natural(0).

Mammals have four legs and no arms or two legs and two arms.

For all X, mammal (x) -> legs(x,4) and arms(x,0) or legs(x,2) and arms(x,2).

Humans have two legs and two arms.For all X, human(x) -> legs(x,2) and arms(x,2).If x is a natural number then so is the successor of x.For all x, natural(x) -> natural(successor(x)).

Page 133: COMP313A Functional Programming (1)

133

First-Order Predicate Calculus

• Constants• Predicates• Functions• Variables that stand for as yet unamed

quantities• Atomic sentences• Connectives construct more complex sentences• Quantifiers• Punctuation• Arguments to predicates can only be terms –

variables, constants and functions

Page 134: COMP313A Functional Programming (1)

134

First-Order Predicate Calculus cont…

• Quanitifiers– Universal, existential

• Express properties of entire collections of objects• Universal quantifiers make statements about

every object, x

A cat is a mammal

x Cat(x) Mammal(x)

Cat(Spot) Mammal(Spot) Cat(Rebecca) Mammal(Rebecca) Cat(Felix) Mammal(Felix) Cat(Richard) Mammal(Richard) Cat(John) Mammal(John) ……

Page 135: COMP313A Functional Programming (1)

135

First-Order Predicate Calculus cont…

• Existential Quantifiers make statements about Existential Quantifiers make statements about some objects, some objects, xx

Spot has a sister who is a catSpot has a sister who is a cat

x Sister(x, Spot) x Sister(x, Spot) Cat(x) Cat(x)

(Sister(Spot, Spot) (Sister(Spot, Spot) Cat(Spot)) Cat(Spot)) (Sister(Rebecca, Spot) (Sister(Rebecca, Spot) Cat(Rebecca)) Cat(Rebecca)) (Sister(Felix, Spot) (Sister(Felix, Spot) Cat(Felix)) Cat(Felix)) (Sister(Richard, Spot) (Sister(Richard, Spot) Cat(Richard)) Cat(Richard)) (Sister(John, Spot) (Sister(John, Spot) Cat(John)) Cat(John)) ……

Page 136: COMP313A Functional Programming (1)

136

First-Order Predicate Calculus cont…

• Connections between and • NegationNegation

Everyone dislikes rugbyEveryone dislikes rugby Noone likes rugbyNoone likes rugby

x x Likes (x, rugby) Likes (x, rugby) x Likes(x, rugby)x Likes(x, rugby)

Everyone likes icecream Everyone likes icecream Noone dislikes icecreamNoone dislikes icecream

x Likes (x, icecream) x Likes (x, icecream) x x Likes(x, icecream)Likes(x, icecream)

Page 137: COMP313A Functional Programming (1)

137

• is a conjunction over the universe of objects

• Is a disjunction over the universe of objects

x P x P

x P x P

x P x P

x P x P

First-Order Predicate Calculus cont…

Page 138: COMP313A Functional Programming (1)

138

De Morgan’s Laws

PQ (PQ)

PQ) PQ PQ PQ)

PQ)PQ

Page 139: COMP313A Functional Programming (1)

139

Using First-Order Predicate Calculus

1. Marcus was a man

2. Marcus was a Pompeian

3. All Pompeians were Romans

4. Caesar was a ruler

5. All Romans were either loyal to Caesar or hated him

Page 140: COMP313A Functional Programming (1)

140

6. Everyone is loyal to someone

7. People only try to assassinate rulers they are not loyal to

8. Marcus tried to assassinate Caesar

Was Marcus loyal to Caesar?

Prove loyalto(Marcus, Caesar)

Page 141: COMP313A Functional Programming (1)

141

• Turn the following sentences into formulae in first order predicate logic

• John likes all kinds of food• Apples are food• Chicken is food• Anything anyone eats and isn’t killed by is food• Bill eats peanuts and is still alive• Sue eats everything Bill eats

• Prove that John likes peanuts using backward chaining

Page 142: COMP313A Functional Programming (1)

142

A little bit of Prolog

• Objects and relations between objects• Facts and rules

parent(pam, bob). parent(tom,bob).parent(tom, liz). parent(bob, ann).parent(bob, pat). parent(pat, jim).

? parent(bob, pat).? parent(bob, liz).? parent(bob, ben).? parent(bob, X).? parent(X, Y).

Page 143: COMP313A Functional Programming (1)

143

Prolog

grandparent (X,Y) :- parent(X, Z), parent(Z, Y).

For all X and Y X is the grandparent of Y if X is a parent of Z and Z is a parent of Y

sister (X,Y) :- parent(Z, X), parent(Z, Y), female(X)

For all X and Y X is the sister of Y if Z is the parent of both X and Y and X is a female