Functional Programming - PowerPoint PPT Presentation

About This Presentation
Title:

Functional Programming

Description:

1987 an international committee of researchers initiates the development of ... odds n = map f [0..n-1] where. f x = x*2 1. can be simplified to ... – PowerPoint PPT presentation

Number of Views:89
Avg rating:3.0/5.0
Slides: 63
Provided by: turing
Category:

less

Transcript and Presenter's Notes

Title: Functional Programming


1
Functional Programming
  • Universitatea Politehnica Bucuresti2008-2009
  • Adina Magda Florea
  • http//turing.cs.pub.ro/fp_09

2
Lecture No. 8 9
  • The Haskell Programming Language
  • Introduction
  • Types and classes
  • Defining functions
  • List comprehensions
  • String comprehensions
  • Recursive functions
  • High order functions

3
Haskell - history
  • 1987 an international committee of researchers
    initiates the development of Haskell, a standard
    lazy functional language
  • 1998 - The committee publishes the Haskell 98
    report, defining a stable version of the language

4
1. Haskell - introduction
  • Haskell is a typeful programming language types
    are pervasive (unlike Scheme)
  • Because Haskell is a purely functional language,
    all computations are done via the evaluation of
    expressions (syntactic terms) to yield values
    (abstract entities that we regard as answers).
  • Every value has an associated type.
  • 5 Integer
  • 'a' Char
  • inc Integer -gt Integer
  • 1,2,3 Integer
  • ('b',4) (Char,Integer)

5
Haskell - introduction
  • All Haskell values are "first-class" - they may
    be passed as arguments to functions, returned as
    results, placed in data structures, etc.
  • Haskell types, on the other hand, are not
    first-class. Types describe values, and the
    association of a value with its type is called a
    typing.

6
Haskell - introduction
  • Functions in Haskell are normally defined by a
    series of equations. For example, the function
    inc can be defined by the single equation
  • inc n n1
  • An equation is an example of a declaration.
  • Another kind of declaration is a type signature
    declaration with which we can declare an explicit
    typing for inc
  • inc Integer -gt Integer
  • In Haskell function application is denoted using
    a space
  • f a b cd
  • Function application has higher priority than all
    other operators
  • f a b -gt (f a) b

7
Haskell - introduction
  • Mathematics
  • f(x)
  • f(x,y)
  • f(g(x))
  • f(x,g(y))
  • f(x)g(y)
  • Haskell
  • f x
  • f x y
  • f (g x)
  • f x (g y)
  • f x g y

8
Naming requirements
  • Function and argument names must begin with lower
    case letters
  • myFun fun1 arg_2
  • By convention, list arguments usually have an s
    suffix on their name
  • xs ns nss
  • In a sequence of definitions, each definition
    must begin in precisely the same column
  • a 10 a 10
  • b 20 b 20
  • c 30 c 30
  • The layout rule avoids the needs for explicit
    syntax to indicate the grouping of definitions

9
2. Types and classes
  • Every expression has a type t, which can be
    automatically calculated at compile time by type
    inference
  • e t
  • type calculates the type of an expression
  • type not False
  • not False Bool
  • Basic types
  • Bool Char
  • String Int (fixed precision)
  • Float Integer (arbitrary precision)

10
Types and classes
  • List type sequence of values of the same type
  • False,True,False Bool
  • Tuple type a sequence of values of different
    types
  • (False, True) (Bool, Bool)
  • (False,'a',True) (Bool, Char, Bool)
  • The list type does not encode its size
  • The type of a tuple encodes its size

11
Function types
  • A function is a mapping from values of one type
    to values of another type
  • not Bool -gt Bool
  • isDigit Char -gt Bool
  • t1 -gt t2 is the type of functions that map values
    of type t1 to values of type t2
  • add (Int,Int) -gt Int
  • add (x,y) x y
  • zeroto Int -gt Int
  • zeroto n 0..n

12
Polymorphic types
  • Polymorphic type expressions - describe families
    of types.
  • a is the family of types consisting of, for
    every type a, the type of lists of a.
  • Lists of integers (e.g. 1,2,3), lists of
    characters ('a','b','c'), even lists of lists
    of integers, etc., are all members of this
    family.
  • a type variable
  • Haskell has only universally quantified types

13
Polymorphic types
  • Polymorphic types - some types are strictly more
    general than others in the sense that the set of
    values they denote is larger.
  • The type a is more general than Char.
  • The latter type can be derived from the former by
    a suitable substitution for a.

14
Polymorphic types
  • With regard to this generalization ordering,
    Haskell's type system possesses two important
    properties
  • every well-typed expression is guaranteed to have
    a unique principal type
  • the principal type can be inferred automatically

15
Polymorphic types
  • An expression's or function's principal type is
    the least general type that, intuitively,
    contains all instances of the expression.
  • head a -gt a
  • head (xxs) x
  • For example, the principal type of head is
    a-gta
  • b-gta, a-gta, or even a are correct types, but
    too general, whereas something like
    Integer-gtInteger is too specific.
  • The existence of unique principal types is the
    hallmark feature of the Hindley-Milner type
    system, which forms the basis of the type systems
    of Haskell, ML, Miranda, and several other
    (mostly functional) languages.

16
Curried functions
  • Functions with multiple arguments are also
    possible by returning functions as results
  • add Int -gt (Int -gt Int)
  • add x y x y
  • add takes an integer x and returns a function add
    x.
  • In turn this function takes an integer y and
    returns the result x y

17
Curried functions
  • add and add_1 produce the same result but add_1
    takes its two arguments at the same time, while
    add takes them one at a time.
  • add_1 (Int,Int) -gt Int
  • add Int -gt (Int -gt Int)
  • Functions that take their arguments one at a time
    are called curried functions, in honor of the
    work of Haskell Curry on such functions

18
Curried functions
  • Functions with more than two arguments can be
    curried by returning nested functions.
  • mult Int -gt (Int -gt (Int -gt Int))
  • mult x y z xyz
  • mult takes an integer x and returns a function
    mult x, which in turn takes an integer y and
    returns a function mult x y, which finally takes
    an integer z and returns the result xyz

19
Curried functions
  • add Integer -gt Integer -gt Integer
  • add x y x y
  • Integer-gtInteger-gtInteger
  • is equivalent to
  • Integer-gt(Integer-gtInteger)
  • i.e. -gt associates to the right.

20
Curried functions
  • As a consequence it is natural for a function
    application to associate to the left
  • mult x y z means ((mult x) y) z
  • Unless tupling is explicitly required, all
    functions in Haskell are normally defined in
    curried form

21
Why currying?
  • Curried functions are more flexible than
    functions on tuples because useful functions can
    often be made by partially applying a curried
    function
  • add 1 Int -gt Int
  • inc add 1
  • This is an example of the partial application of
    a curried function, and is one way that a
    function can be returned as a value.

22
Why currying?
  • Pass a function as an argument.
  • The map function is a perfect example
  • map (a-gtb) -gt a -gt b
  • map f
  • map f (xxs) f x map f xs
  • This is an example of the partial application of
    a curried function, and is one way that a
    function can be returned as a value.

23
Polymorphic functions
  • A function is called polymorphic if its type
    contains one or more type variables
  • length a -gt Int
  • head a -gt a
  • id a -gt a
  • Type variables must begin with lower case letters
    and are usually named a, b, c, etc.
  • Type variables can be instantiated to different
    types in different circumstances
  • length False, True
  • length 1,2,3,4

24
Overloaded functions
  • A polymorphic function is called overloaded if
    its type contains one or more class constraints
  • sum Num a gt a -gt a
  • For any numeric type a, sum takes a list of
    values of type a and returns a value of type a
  • Constrained type variables can be instantiated to
    any types that satisfy the constraint
  • sum 1,2,3
  • sum 1.1, 2.2, 3.3
  • sum 'a', 'b', 'c' ERROR

25
Type classes
  • Haskell has a number of type classes, including
  • Num Numeric types
  • Eq Equality types
  • Ord Ordered types
  • () Num a gt a -gt a -gt a
  • () Eq a gt a -gt a -gt Bool
  • (lt) Ord a gt a -gt a -gt Bool

26
3. Defining functions
  • Conditional expressions
  • abs Int -gt Int
  • abs n if n gt 0 then n else -n
  • signum Int -gt Int
  • signum n if n lt 0 then -1 else
  • if n 0 then 0 else 1
  • In Haskell, conditional expressions must always
    have an else branch, which avoids any possible
    ambiguity problems with nested conditionals

27
Guarded equations
  • As an alternative to conditionals, functions can
    also be defined using guarded equations
  • abs Int -gt Int
  • abs n n gt 0 n
  • otherwise -n
  • Guarded equations can be used to make definitions
    involving multiple conditions easier to read
  • signum Int -gt Int
  • signum n n lt 0 -1
  • n 0 0
  • otherwise 1

28
Pattern Matching
  • Many functions have a particularly clear
    definition using pattern matching on their
    arguments
  • not Bool -gt Bool
  • not False True
  • not True False

29
Pattern Matching
  • Functions may be defined in many different ways
    using pattern matching
  • () Bool -gt Bool -gt Bool
  • True True True
  • True False False
  • False True False
  • False False False
  • can be defined more compactly by
  • True True True
  • _ _ False

30
Pattern Matching
  • The following definition is more efficient
  • True b b
  • False _ False
  • Patterns are matched in order. For example the
    following definition returns False
  • _ _ False
  • True True True
  • Patterns may not repeat variables. For example,
    the following definition gives an error
  • b b b
  • _ _ False ERROR

31
List patterns
  • List cons operator
  • 1,2,3,4 means
  • 1(2(3(4)))
  • Functions on lists can be defined using xxs
    patterns
  • head a -gt a
  • head (x_) x
  • tail a -gt a
  • tail (_xs) xs
  • xxs patterns must be parenthesised. For example,
    the following definition gives an error
  • head x_ x ERROR

32
Integer patterns
  • Functions on integers can be defined using nk
    patterns, where n is an integer variable and kgt0
    is an integer constant
  • pred Int -gt Int
  • pred (n1) n
  • nk patterns only match integers kgt0
  • pred 0 ERROR
  • nk patterns must be parenthesised because
    function application has priority over
  • pred n1 n ERROR

33
Lambda expressions
  • Functions can be constructed without naming the
    functions by using lambda expressions
  • lambda expressions can be used to give a formal
    meaning to functions using currying
  • add x y xy
  • means
  • add \x -gt (\y -gt xy)

34
Lambda expressions
  • odds n map f 0..n-1
  • where
  • f x x2 1
  • can be simplified to
  • odds n map (\x -gt x2 1) 0..n-1

35
Sections
  • An operator written between its two arguments can
    be converted into a curried function written
    before its two arguments by using parentheses
  • () 1 2 3
  • This convention allows one of the arguments of
    the operator to be included in the parentheses
  • (1) 2 3
  • (2) 1 3
  • In general, if _at_ is an operator then functions of
    the form (_at_), (x_at_) and (_at_y) are called sections.

36
Why sections ?
  • Useful functions can sometimes be constructed in
    a simple way using sections. For example
  • (1) - successor function
  • (1/) reciprocation function
  • (2) doubling function
  • (/2) halving function

37
4. List comprehensions
  • In mathematics, the comprehension notation can be
    used to construct new sets from old sets
  • x2 x ? 1..5
  • In Haskell, a similar comprehension notation can
    be used to construct new lists from old lists
  • x2 x lt- 1..5 1,4,9,16,25
  • The expression x lt- 1..5 is called a generator
    as it states how to generate values for x

38
List comprehensions
  • Comprehensions can have multiple generators,
    separated by commas
  • (x,y) x lt- 1,2,3, ylt- 4,5
  • (1,4),(1,5),(2,4),(2,5),(3,4),(3,5)
  • Changing the order of the generators changes the
    order of the elements in the final list
  • (x,y) ylt- 4,5, x lt- 1,2,3
  • (1,4),(2,4),(3,4),(1,5),(2,5),(3,5)
  • Multiple generators are like nested loops with
    later generators as more deeply nested loops
    whose variables change value more frequently

39
Dependent generators
  • Later generators can depend on the variables that
    are introduced by earlier generators
  • (x,y) x lt- 1..3, ylt- x..3
  • (1,1),(1,2),(1,3),(2,2),(2,3),(3,3)
  • Using a dependant generator we can define the
    library function that concatenates a list of
    lists
  • concat a -gt a
  • concat xss x xs lt- xss, x lt- xs
  • concat 1,2,3,4,5,6 1,2,3,4,5,6

40
Guards
  • List comprehensions can use guards to restrict
    the values produced by earlier generators
  • x x lt- 1..10, even x
  • 2,4,6,8,10
  • Using a guard we can define a function that maps
    a positive integer to its list of factors
  • factors Int -gt Int
  • factors n x x lt- 1..n, n mod x 0
  • factors 15 1,3,5,15

41
Guards
  • Using factors we can define a function that
    decides if a number is prime
  • prime Int -gt Bool
  • prime n factors n 1,n
  • prime 15 False
  • prime 7 True

42
Guards
  • Using a guard we can now define a function that
    returns the list of all primes up to a given
    limit
  • primes Int -gt Int
  • primes n x x lt- 2..n, prime x
  • primes 40
  • 2,3,5,7,11,13,17,19,23,29,31,37

43
The Zip function
  • A useful library function is zip, which maps two
    lists to a list of pairs of their corresponding
    elements
  • zip a -gt b -gt (a,b)
  • zip 'a','b','c' 1,2,3
  • ('a',1),('b',2),('c',3)

44
The Zip function
  • Using zip we can define a function that returns
    the list of all pairs of adjacent elements from a
    list
  • pairs a -gt (a,a)
  • pairs xs zip xs (tail xs)
  • pairs 1,2,3,4
  • (1,2),(2,3),(3,4)

45
Is the list sorted?
  • Using pairs we can define a function that decides
    if the elements in a list are sorted
  • sorted Ord a gt a -gt Bool
  • sorted xs
  • and xlt y (x,y) lt- pairs xs
  • sorted 1,2,3,4
  • True

46
Positions
  • Using zip we can define a function that returns
    the list of all positions of a value in a list
  • positions Eq a gt a -gt a -gt Int
  • positions x xs
  • i (x',i) lt- zip xs 0..n, x x'
  • where n length xs - 1
  • positions 0 1,0,0,1,0,1,1,0
  • 1,2,4,7

47
5. String comprehensions
  • Internally, strings are represented as lists of
    characters
  • "abc" String 'a','b','c' Char
  • Because strings are just special kinds of lists,
    any polymorphic function that operates on lists
    can also be applied to strings
  • length "abc" 3
  • take 3 "abcde" "abc"
  • zip "abc" 1,2,3,4
  • ('a',1),('b',2),('c',3)

48
String comprehension
  • List comprehension can be used to define
    functions on strings
  • Ex function that counts the lower case letters in
    a string
  • lowers String -gt Int
  • lowers xs
  • length x x lt- xs, isLower x
  • lowers "Haskell" 6

49
6. Recursive functions
  • length a -gt Int
  • length 0
  • length (_xs) 1 length xs
  • reverse a -gt a
  • reverse
  • reverse (xxs) reverse xs x

50
Recursive functions
  • zip a -gt b -gt (a,b)
  • zip _
  • zip _
  • zip (xxs) (yys) (x,y) zip xs ys
  • () a -gt a -gt a
  • ys ys
  • (xxs) ys x (xs ys)
  • drop Int -gt a -gt a
  • drop 0 xs xs
  • drop (n1)
  • drop (n1) (_xs) drop n xs

51
Recursive functions
  • sort Int -gt Int
  • sort
  • sort (xxs)
  • sort smaller x sort larger
  • where
  • smaller a a lt- xs, alt x
  • larger b b lt- xs, bgtx

QUCKSORT Non-empty lists can be sorted by
sorting the tail values lt the head sorting the
tail values gt the head and then appending the
resulting lists on either side of the head value
52
High-order functions
  • The next slides are based on
  • Programming in Haskell,
  • Graham Hutton,
  • Cambridge University Press (January 15, 2007)

53
7. High-order functions
  • A function is called higher order if it takes a
    function as an argument or returns a function as
    a result
  • twice (a -gt a) -gt a -gt a
  • twice f x f (f x)

54
The Map function
  • map is a library function applies a function to
    every element of a list
  • map (a -gt b) -gt a -gt b
  • map f xs f x x lt- xs
  • map f
  • map f (xxs) f x map f xs
  • map (1) 1,3,5,7 2,4,6,8

55
The Filter function
  • filter is a library function selects every
    element of a list that satisfies a predicate
  • filter (a -gt Bool) -gt a -gt a
  • filter p xs x x lt- xs, p x
  • filter p
  • filter p (xxs)
  • p x x filter p xs
  • otherwise filter p xs
  • filter even 1..10 2,4,6,8,10

56
The Foldr function
  • A number of functions on lists can be defined
    using the following simple pattern of recursion
  • f v
  • f (xxs) x op f xs
  • f maps the empty list to some value v and any
    non-empty list to some function op applied to its
    head and f of its tail

57
The Foldr function
  • For example
  • sum 0
  • sum (xxs) x sum xs
  • product 1
  • product (xxs) x product xs
  • and True
  • and (xxs) x and xs

58
The Foldr function
  • The higher order function foldr (fold right)
    encapsulates this simple pattern of recursion,
    with the function op and the value v as arguments
  • sum foldr () 0
  • product foldr () 1
  • or foldr () False
  • and foldr () True

59
The Foldr function
  • foldr (a -gt b -gt b) -gt b -gt a -gt b
  • foldr f v v
  • foldr f v (xxs) f x (foldr f v xs)
  • However it is best to think of foldr
    non-recursively as simultaneously replacing each
    () in a list by a given function and by a
    give value

60
The Foldr function
  • sum 1,2,3
  • foldr () 0 1,2,3
  • foldr () 0 (1 (2 (3 )))
  • 1 (2 (3 0)) 6
  • product 1,2,3
  • foldr () 1 1,2,3
  • foldr () 1 (1 (2 (3 )))
  • 1 (2 (3 1)) 6

Replace each () by () and by 0
Replace each () by () and by 1
61
The Foldr function
  • sum 1,2,3
  • foldr () 0 1,2,3
  • foldr () 0 (1 (2 (3 )))
  • 1 (2 (3 0)) 6
  • product 1,2,3
  • foldr () 1 1,2,3
  • foldr () 1 (1 (2 (3 )))
  • 1 (2 (3 1)) 6

62
The Composition function
  • The library function (.) returns the composition
    of two functions as a single function
  • (.) (b -gt c) -gt (a -gt b) -gt (a -gt c)
  • f . g \x -gt f (g x)
  • odd Int -gt Bool
  • odd not . even
Write a Comment
User Comments (0)
About PowerShow.com