* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download LN10
Falcon (programming language) wikipedia , lookup
Curry–Howard correspondence wikipedia , lookup
Lambda calculus definition wikipedia , lookup
Closure (computer programming) wikipedia , lookup
Combinatory logic wikipedia , lookup
Lambda calculus wikipedia , lookup
Intuitionistic type theory wikipedia , lookup
Lambda lifting wikipedia , lookup
C Sharp (programming language) wikipedia , lookup
Com2010 - Functional Programming Higher Order Functions and Computation Patterns (I) Marian Gheorghe Lecture 10 Module homepage Mole & http://www.dcs.shef.ac.uk/~marian com2010 ©University of Sheffield Haskell II -Summary • • • Teaching; weeks 7-9, 3h/week Project; weeks 10-12 Topics: 1. Higher order functions, Algebraic data types, Lazy programming, Regular expressions, Abstract data types: 5 h – concepts 2. Lexical analysis and parsing: 3h – case study, Soft Eng approach 3. Demo Lex & Parse: 1h 1&2 links with other topics –machine, languages, distributed computation • Project discussion: 1h (TBA) Timetable: Mon: 4.10-5.00pm; Wed: 10.00-10.50am; Thu: 12.10-1.00pm com2010 ©University of Sheffield Why Functional Programming? • Different (functional vs imperative) • Natural constructs (implement TCS concepts: set, function, morphism, recursion) • Easy to understand and use (?!) • Useful… com2010 ©University of Sheffield Example Python is an object-oriented language used in software development http://www.python.org/ It has the following characteristics • Very clear, readable syntax • Intuitive object orientation • Natural expression of procedural code • Full modularity and packages • Exception-based error handling • Similarities to C, C++, Java etc. com2010 ©University of Sheffield Example – OO style we can write an initial sub-sequence of the Fibonacci series as follows: # Fibonacci series:... # the sum of two elements defines the next... a, b = 0, 1 while b < 10 print b a, b = b, a+b com2010 ©University of Sheffield Example – Functional style but… we can define functions >>> def cube(x): return x*x*x and map them >>> map(cube, range(1, 11)) [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000] it supports list comprehension >>> vec = [2, 4, 6] >>> [3*x for x in vec] [6, 12, 18] and membership testing set(['orange', 'pear', 'apple', 'banana']) >>> 'orange' in fruit # fast membership testing True com2010 ©University of Sheffield Summary 18. Higher-Order Functions and Computation Patterns 18.1 The function type a->b 18.2 Arity and infix 18.3 Iteration and primitive recursion 18.4 Efficiency and recursion patterns 18.5 Partial functions and errors 18.6 More higher-order on lists com2010 ©University of Sheffield HOF - Introduction In any functional programming language that deserves its name, functions are first-class citizens. They form a data type and thus can be passed as arguments and returned as values. Functions of type (a->b) -> c take functions of type a->b as input and produce a result of type c. Functions of type a -> (b->c) take values of type a as arguments and produce functions of type b -> c as results. com2010 ©University of Sheffield HOF - Definition Definition. A function is higher-order if it takes a function as an argument or returns a function as a result, or both. Higher-order functions we have seen in Chapter 16.2 map :: (a->b)->[a]->[b] filter :: (a->Bool)->[a]->[a] foldr :: (a->b->b)->b->[a]->b merge :: (a->a->Bool)->[a]->[a]->[a] mergesort :: (a->a->Bool)->[a]->[a] Do you remember what they do? com2010 ©University of Sheffield Function type 18.1 The function type a->b (“Haskell is strongly typed” – PDG’s notes, p.7) Objects of type a->b are constructed by lambda abstraction \x->e and used in function application f e’. Lambda abstraction: if e has type b and x is a variable of type a then \x->e has type a->b Function application: if f has type a->b and e’ has type a then f e’ has type b Expressions such as \x->e are also called lambda expressions, or anonymous functions, in contrast to functions that are declared and bound to a name by definition equations. com2010 ©University of Sheffield Function type: Example The function definition double::Int->Int double x=2*x defines the behaviour of double point-wise. i.e. for every argument x. This definition has the same effect as double::Int->Int double=(\x->2*x) defines double wholesale. The anonymous function \x->2*x is an expression for the complete function. -> associates to the right. We may write a->b->c->d instead of a->(b->(c->d)). Similarly, \x -> \y -> \z -> x + y + z rather than \x ->(\y ->(\z->x + y + z)); \x y z->x + y + com2010 ©University of Sheffield z Function composition A simple example of an operator on functions is function composition: fcomp::(b->c)->(a->b)->a->c fcomp g f x=g (f x) Function composition - its own operator symbol in Haskell Prelude: (.)::(b->c)->(a->b)->a->c (g.f) x=g (f x) or (g.f)=(\x->g (f x)) This is called an infix operator definition com2010 ©University of Sheffield Types and arity Type definitions in Haskell. A type definition for a function is foo :: a1->a2 …->an->t where ai and t are type expressions. The types in the list a1 a2 … an refer to the parameters. Their number n is the so-called arity of foo. A typical function definition for foo consists of guarded equations foo p1 p2 … pn | g1 = b1 … | gk = bk com2010 foo p1 | g1 = b1 … | gk = bk ©University of Sheffield Infix operators For functions of arity 2 we can use infix notation. For instance, (.)::(b->c)->(a->b)->a->c (.)(g f) x=g (f x) which is usually written as (g.f) in infix notation. Ex: eightTimes::(Int -> Int) eightTimes=double . double . double as abbreviation for (.) double ((.) double double)) or double . (double . double) com2010 ©University of Sheffield Partial applications- application of prefix definition The function ++ concatenates two strings: (++)"Name=" "Bill" ⇒ "Name=Bill" Its type is String -> String -> String. According to the rules of function application we can also apply it to only one argument: infixr 5 ++ (++)::String->(String->String) (++)”Name=”::String->String The result (++) "Name = " is a one-argument prefAll::[String]->[String] -- prefix all elements in a list of strings prefAll names = map((++)"Name=")names prefAll ["Bill","John","Tony"] ⇒ ["Name=Bill","Name=John","Name=Tony"] com2010 ©University of Sheffield Iteration - example Example. The function exp2::Int->Int could be mathematically defined (using double) as follows: exp2(n)=2n=2*(2n-1)=2*exp2(n-1)=double(exp2(n-1)), n>0 exp2(0)=1 We may define exponentiation with base 2 by a recursive computation exp2::Int->Int exp2 n | n==0 = 1 | n>0 = double(exp2 (n-1)) (the last line may be written differently) Obs. For every (positive) n the expression exp2 n iterates the function double com2010 ©University of Sheffield Iteration - pattern The process of iterating a function is very general: myIter::(a->a)->a->Int->a iterates a function of type a->a starting with an initial value (of type a), for a given number of steps (type Int) myIter::(a->a)->a->Int->a -- 1st param: iteration function -- 2nd param: initial value -- 3rd param: iteration length myIter f x n | n==0 = x | n>0 = f (myIter f x (n-1)) The polymorphic higher-order function myIter captures the abstract process of iteration. com2010 ©University of Sheffield Iteration. Example revisited Example -Exponentiation: myExp2::(Int->Int) myExp2 = myIter double 1 Consider the problem of computing the exponent bn for arbitrary b. exp b n =bn, n>0; exp b 0 =1 All we do is replace double by the anonymous function \x->b*x: myExp::Int->(Int->Int) myExp b = myIter (\x->b*x) 1 Example. Construct a list [‘c’,...,’c’] repChar::Char->(Int->[Char]) repChar c = myIter (\x->c:x) [] Obs. Note the conciseness of myIter and the use of anonymous function com2010 ©University of Sheffield