Survey

Survey

Document related concepts

Transcript

Introduction Into Functional Programming Lecture given at the American University in Bulgaria (Blagoevgrad) Prof. Dr. Jürgen Vollmer <[email protected]> April 15, 2011 Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / / 1(112) April 15, 2011 Why another programming language? A computer scientist ... ... is not defined by “speaking” one or two special programming languages, every hacker can do so. Computer scientists are characterized by mastering the principle of programming and by the ability to express them self in programming languages [P EPPER 2003]. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ What is it? 2(112) April 15, 2011 Characteristics: functional & imperative languages Differences Property Idea Operation Result Notation Objects Languages Functional Input / output relation, functions function application y = sin(x) is “timeless” mathematical mathematical L ISP , ML, H ASKELL , M IRANDA Imperative Memory, instructions, commands Assignment x := x + 1 depends on the “state” (memory) which changes over time machine instruction Bits & Bytes A LGOL , F ORTRAN , C OBOL , PASCAL , C, J AVA Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ What is it? 3(112) April 15, 2011 Properties of functional programming languages Advantages I Programs are functions I Functions are data I Side effects are limited I Automatic garbage collection Drawbacks I Unfamiliar “way of thinking” I Typically interpreted I Quite often inefficient execution Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ What is it? 4(112) April 15, 2011 Properties of functional programming languages Range of applications I Creating prototypes I Artificial intelligence I Automatic proof systems Haskell I I Web server mohws [M ARLOW 2002] http://code.haskell.org/mohws/README I Web Authoring System Haskell WASH [T HIEMANN 2002] I http://www.informatik.uni-freiburg.de/~thiemann/haskell/WASH Unix X-Windows system xmonad [S TEWART and J ANSSEN 2007], http://en.wikipedia.org/wiki/Xmonad Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ What is it? 5(112) April 15, 2011 Textbooks and more literature Textbooks I Peter H. S ALUS: Functional and Logic Programming Languages, 1998 I Kenneth C. L OUDEN: Programming Languages, Principles and Practice, chapter 11, 2002 I Michael L. S COTT: Programming Languages Pragmatics, chapter 10, 2009 I Patrick Henry W INSTON and Bertold Klaus Paul H ORN: LISP, 1989 Fundamentals Papers I John Warner B ACKUS: Can Programming Be Liberated From the Von Neumann Style? A Functional Style and its Algebra of Programs, 1978 I John H UGHES: Why Functional Programming Matters, 1989 Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ What is it? 6(112) April 15, 2011 MIT CADR Lisp-Machine, 1977/1978 Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ What is it? 7(112) April 15, 2011 George Orwell If thought can corrupt language, so the language can corrupt our thoughts. (Politics and the English Language) Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Models of computation 8(112) April 15, 2011 Models of computation Definition (Computation) A computation, in the sense of computer science is the execution of some instructions by a machine, returning some results. Definition (Computation Model) Memory oriented models ⇒ x := x + 1; Programming languages: C, C++, C#, Java, Perl, . . . Functional models ⇒ f (x) = x 2 + 2x + 3 Programming languages: Lisp, ML, Haskell, . . . Logical models ⇒ Brother (x,y) :- Father(x,z), Father(y,z). Programming languages: Prolog, Make, . . . Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Models of computation 9(112) April 15, 2011 Memory Oriented Computation Model Example (Imperative programming: Calculate 1 + 2 + · · · + n) 1. In the drawer with the name i the number n is “put”. 2. In the drawer with the name result, the number 0 is “put”. 3. Take the numbers from the drawers i and result. “Put” the sum of both numbers into the result drawer. The number in the i drawer remains unchanged. 4. Take the number for the i drawer and put the decremented by 1 number back. 5. Take the number for the i drawer. 5.1 If the number is equal to 0 terminate. The result of the computation is contained in the result drawer. 5.2 Otherwise continue with step 3. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Models of computation 10(112) April 15, 2011 Functional Computation Model Example (Calculate the sum of the numbers 1, 2, . . . , n) Use the formula: 1+2+···+n = n × (n + 1) 2 for the calculation. Example (Calculate the product n! of a positive natural number n (factorial function)) n! = 1 (n − 1)! × n if n = 1 if n > 1 Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Models of computation 11(112) April 15, 2011 Definitions Definition (Function) I I I A function is a relation between a given set of elements called the domain and a set of elements called the codomain. The function associates each element in the domain with at most one element in the codomain. If f the name of the function, one can write y = f (x) or f :X →Y I I I x is called an independent variable and y is called dependent variable. If f is not defined for all x ∈ X , then f is called a partial function . If f is defined for all elements of X , then f is called a total function. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Programs as Functions 12(112) April 15, 2011 Definitions Definition (Program) A program is the textual description of a specific calculation. A program can be seen as a black box. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Programs as Functions 13(112) April 15, 2011 Definitions Definition (Progr. lang.: Object, Declaration, Definition, Usage) A programming language deals with objects like variables, procedures, functions, data types, files etc. Declaration I I gives a name to an object attaches properties to an object Definition assigns a value to an object Usage access of an object Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Programs as Functions 14(112) April 15, 2011 Definitions Definition (Function: Declaration, Definition, Application (Call)) Functions are programming language objects: function declaration I I name and signature and other properties formal parameters function definition I I program text specifying the “what” and “how” Note: function value: “program code” and not the “computed value” function usage: function application, (evaluation, call) 1. replace formal parameters by actual parameters 2. execute calculation given in the definition, using passed parameters Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Programs as Functions 15(112) April 15, 2011 Definitions Definition (Variable) I Imperative languages I I I (imperative) variable is a name of a memory cell Memory contents is changed by means of assignment operator = (C, Java) assign statement := (Pascal, Modula) In mathematics a (mathematical) variable always designates an arbitrary, but immutable value. Example (Variable) Imperative “x = x + 1;” Mathematical “Let x be so that √ x = 2” Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Programs as Functions 16(112) April 15, 2011 Definitions Definition (Purely Functional Language) Waived a functional programming language on any kind of assignment, it is called a purely functional language. Most functional languages, however, have some “kind” of assignment, i. e. of state information that may be changed. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Programs as Functions 17(112) April 15, 2011 Loops? Question Can a purely functional programming language have a while or for loop? Answer NO! Why: I I I The body of the loop is executed as long as the loop-condition evaluates to “true”. To terminate the loop, the condition must be evaluated to “false” eventually. The loop must contain some imperative variables whose value is changed, so that the condition may be evaluated to “false”. SOS!!! HELP!!!!!!! How can we program without the presence of loops????? =⇒ Recursion! Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Programs as Functions 18(112) April 15, 2011 L. P ETER D EUTSCH und R OBERT H ELLER To Iterate is Human, to Recurse is Divine Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Recursion 19(112) April 15, 2011 To Iterate is Human, to Recurse is Divine Recursion is . . . I an approach to solve problems, which I I I delivers simple solutions for some issues, which would otherwise be difficult to solve! Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Recursion 20(112) April 15, 2011 To Iterate is Human, to Recurse is Divine Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Recursion 21(112) April 15, 2011 To Iterate is Human, to Recurse is Divine Example (Painting a Matryoshka) 1. Paint the doll. 2. If doll can be opened, then 2.1 disassemble the doll, and 2.2 paint that (inner) doll. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Recursion 22(112) April 15, 2011 To Iterate is Human, to Recurse is Divine Example (Searching an Encyclopedia) 1. Flip the book open in the middle 2. If the word is contained on the pages, then 2.1 we’re done; else: 2.2 If the searched word is “less” then the shown ones, then 2.2.1 continue search within the left half of the book; otherwise 2.2.2 continue search within with the right half of the book. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Recursion 23(112) April 15, 2011 To Iterate is Human, to Recurse is Divine Example (Towers of Hanoi) Rules: 1. At a time, only one plate will be moved; 2. A plate may never be layed on a smaller one To play in your browser: http://www.mah-jongg.ch/towerofhanoi Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Recursion 24(112) April 15, 2011 To Iterate is Human, to Recurse is Divine Algorithm: Towers of Hanoi Input A tower of Hanoi with n plates on a pile Start. Output A sequence of moves, which move the plates to the goal pile (Z), obeying the two rules. The “helper” pile H may be used. Method “Move n plates from S to Z , using helper pile H” How it’s onging now??????? Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Recursion 25(112) April 15, 2011 To Iterate is Human, to Recurse is Divine Example (Tower of Hanoi with three plates) “Move n plates from S to Z , using helper pile H” 1. If n = 1 1.1 then move plate from S to Z , finished; 1.2 else 1.2.1 move n − 1 plates from S to H using helperpile Z . 1.2.2 print:: “remaining plate from S to Z .” 1.2.3 move n − 1 plates from H to Z using helper pile S. V(3, B →A, C) A Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Recursion B C 26(112) April 15, 2011 To Iterate is Human, to Recurse is Divine Recursion: The General Approach I If the problem size is “small enough” ⇒ solve it directly. I Otherwise Divide it into one or several small subproblems to ⇒ Solve each subproblem recursively. I Join the partial results to get the complete solution. I Recursion: How to design it? I I Identify the recursion base, i. e. those cases for which the task can be solved “directly” without using the recursive algorithm. Develop a method to partition the problem. I I I The sub problems must be smaller in size. The sub problems should led to the recursion base. Develop a method to combine the sub solutions in order to get the complete solution. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Recursion 27(112) April 15, 2011 To Iterate is Human, to Recurse is Divine Recursion 6= Top-Down Top-down: break down a system into its compositional sub-systems Top-Down partition into sub tasks ⇒ solve them using different methods. Recursion partition set of input data ⇒ use same method on smaller problem input size Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Recursion 28(112) April 15, 2011 To Iterate is Human, to Recurse is Divine Example (Length of a Character String) Recursion base If the string is empty, its length is 0, otherwise Recursion Compute the length L of the string without the first letter; the combined result is L + 1. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Recursion 29(112) April 15, 2011 Iteration vs. Recursion Definition (Greatest Common Divisor, Greatest Common Factor) The greatest common divisor or greatest common factor of two natural numbers is the largest positive integer that divides the numbers without a remainder. Algorithm: Greatest Common Divisor, iterative 1 2 3 4 5 6 7 8 9 i n t gcd ( i n t a , i n t b ) { while ( b != 0 ) { int t = b; b = a % b; a = t; } return a ; } Example (gcd (12, 34); iterative) Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Recursion 30(112) April 15, 2011 Iteration vs. Recursion Theorem (Greatest Common Divisor) Let a, b ∈ N then gcd(a, b) = a gcd(b, a mod b) if b = 0 otherwise =⇒ Algorithm: Greatest Common Divisor, recursive 1 2 3 4 5 6 7 8 i n t gcd ( i n t a , i n t b ) { i f ( b == 0 ) { return a ; } else { r e t u r n gcd ( b , a % b ) ; } } Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Recursion 31(112) April 15, 2011 Properties Definition (Referential Transparency) Depends the outcome of the evaluation of an expression or function only on the values of the actual parameters, that computation is called to be referential transparent. In other words, a program that has always the same effects and output on the same input. Note I In mathematics, each evaluation is referential transparent. I In imperative programming computations are often not referential transparent. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Properties of Functional Programming 2011 32(112) April 15, Properties Consequences of Referential Transparency I The order of evaluation of the current parameters is irrelevant: In contrast to: foo (2 * i++, 2 * ++i, i) I Function calls return to each call with the same arguments, the same results. Algorithm: Function with an internal state 1 2 3 4 5 6 int i = 0; i n t bar ( i n t j ) { i ++; return j + i ; } I Note: functions like random() or date() are not referential transparent! Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Properties of Functional Programming 2011 33(112) April 15, Properties Consequences of Referential Transparency I Referentially transparent programs are easier to understand because there is no “context” and no “call history”. I This property also sometimes called value semantics, as opposed to pointer semantics or memory semantics of imperative programming languages. I In functional languages, variables identify only values. I In imperative languages, variables identify only memory cells. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Properties of Functional Programming 2011 34(112) April 15, Properties Definition (Strict / Lazy Evaluation) Functional programming languages can be distinguished in terms of their evaluation strategies of the actual parameters: I Using strict evaluation the values of all actual parameters are computed before the function is called. This corresponds to behavior of imperative programming languages. I Using lazy evaluation the values of an actual parameter is computed only if it is really needed by the function. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Properties of Functional Programming 2011 35(112) April 15, 36(112) April 15, Evaluation Strategies Algorithm: Strict / Lazy Evaluation in C 1 2 3 4 5 6 7 8 i n t cond ( i n t a , i n t b , i n t c ) { if (a) { return b ; } else { return c ; } } 9 10 11 r e s = cond ( x < y , x , pow ( s i n ( x ) + cos ( y ) , 2 . 8 ) ) ; 12 13 14 r e s = ( x < y ) ? x : ( pow ( s i n ( x ) + cos ( y ) , 2 . 8 ) ) ) ; 15 16 17 r e s = ( x != 0 ) ? ( y / x ) : 0 ; 18 19 20 21 i f ( c o n d i t i o n && f ( . . . ) ) { . . . } else { . . . } i f ( c o n d i t i o n | | f ( . . . ) ) { . . . } else { . . . } Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Properties of Functional Programming 2011 Evaluation Strategies Comparison Strict vs. Lazy Evaluation of Function Arguments strict Usually more efficient than lazy, as no “unevaluated expression” have to be passed to the function. But compilers may apply sophisticated strictness analyses on the programs in order to perform strict evaluation of arguments whenever possible. lazy Lazy evaluation allows passing of cyclical or potential infinite data structures to functions. The parameter passing mechanism, “call-by-name” offered by languages like Algol, or the C preprocessor, implement that kind of demand driven evaluation of arguments. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Properties of Functional Programming 2011 37(112) April 15, Definitions Definition (First and Higher Order Programming Languages) I I Programming languages that permit only the declaration and call of functions, are called first order languages. Programming languages I I I which deal with functions as ordinary values, allow functions to be passed as arguments to other functions permit functions to be returned as values from functions are called higher order languages. I Functions in higher order languages are called first-class values. They are is no difference to other first class values such as numbers, characters, arrays, etc. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Functions as Data 38(112) April 15, 2011 Definitions Definition (Function Composition) Given two functions f : X → Y and g : Y → Z , then g ◦f : X → Z (“g composed with f”, or “g after f”) is a function and is defined as (g ◦ f )(x) = g(f (x)) Example (Function composition) g ◦ f , the composition of f and g, for example, (g ◦ f )(c) = #. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Functions as Data 39(112) April 15, 2011 Definitions Remarks I g ◦ f is a “autonomous” function, and not just a “nested call” of two functions. I ◦ is an operator over functions, i. e. it accepts two functions as an argument and returns a function. Theorem (Function composition) Function composition is associative. (h ◦ g) ◦ f = h ◦ (g ◦ f ) Proof: show that for any x the left and right side of the proposition hold Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Functions as Data 40(112) April 15, 2011 Summary 1. Functions have a clear distinction between input parameters and output results. 2. There are no memory variables, and therefore no assignments. 3. There are no loops but recursion. 4. Functions are referentially transparent: I I the result depends only on the input parameters; functions have no internal state. 5. Functions are first class values. 6. Evaluation of the input parameters may be strict or lazy. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Introduction/ Functions as Data 41(112) April 15, 2011 B RIAN K ERNIGHAN The only way to learn a new programming language is to write programs in it. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ 42(112) April 15, 2011 Haskell Haskell [H UDAK, P EYTON J ONES, and WADLER 1992], [http://www.haskell.org] I Haskell is a standardized, general-purpose purely functional programming language, with non-strict semantics and strong static typing. I Named after H ASKELL B ROOKS C URRY (1900 – 1982) I Defined in 1990, open source, allows rapid development of robust, concise, correct software. I Haskell has strong support for integration with other languages, built-in concurrency and parallelism, debuggers, profilers, rich libraries and an active community. I Haskell is based on the Lambda Calculus, therefore its logo Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ 43(112) April 15, 2011 Haskell Development Environments The Glasgow Haskell Compiler (GHC) is a development environment for Haskell and consists of an I Interpreter I Compiler I Debugger I Library GHC may be downloaded from http://haskell.org/ghc for all usual operating systems (Linux, Mac, Windows) Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ 44(112) April 15, 2011 Haskell Manuals and Text Books I A Gentle Introduction to Haskell 98 [H UDAK, P ETERSON, and FASEL 1999] and [http://www.haskell.org/tutorial] I Yet Another Haskell Tutorial [DAUMEÉ III 2002] and [http://darcs.haskell.org/yaht/yaht.pdf] I A web site with lots of links to Haskel tutorials [http://www.haskell.org/haskellwiki/Tutorials] I Report on the programming language Haskell: a non-strict, purely functional language version 1.2 [H UDAK, P EYTON J ONES, and WADLER 1992] and [http://www.haskell.org/haskellwiki/Language_and_library_specification] I The main Haskell web site: [http://www.haskell.org] Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ 45(112) April 15, 2011 46(112) April 15, 2011 Haskell Definition (Haskell-Program) A Haskell-Program consists of I values (Data), I function definitions and I one result expression. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Predefined Data Types Definition (Data Type) A data type describes a (finite or infinite) set of values. The name of a data type begins with a capital letter. Definition (Predefined Data Types) Predefined data types are: Int Float Double Char String Bool integral numbers of arbitrary size floing point numbers floing point numbers (Unicode)-characters character strings of arbitrary length boolean truth values Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Values and Functions 47(112) April 15, 2011 Values Definition (Atomic Values) An atomic value is a value of a one of the predefined data types. Example (Atomic Values) 5 3.141 ’a’ "Hello World!" True, False an integral number a floating point number a character a character string truth values Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Values and Functions 48(112) April 15, 2011 Functions Definition (Computation) A computation is the evaluation of an expression to values. Example (Computation) 2 × sin(45◦ ) ⇒ 2 | {z } | × 0.7071 {z } ⇒ 1.4142 | {z } expression expression value Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Values and Functions 49(112) April 15, 2011 Functions Definition (Function, - Definition, - Call, - Application) I A function maps values onto values. I A Haskell-function is defined by one or more equations. An equation has the form: head = body I The function head consists of the function’s name followed by the formal parameters. I The function body is an expression. I Names of functions and formal parameters start with a small letter. I function call (application): name arg1 arg2 ... argn Algorithm: Haskell: Definition and call of a function: increment 1 2 4 5 6 −− D e f i n i t i o n increment x = x + 1 −− C a l l / A p p l i c a t i o n increment 2 ==> 3 Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Values and Functions 50(112) April 15, 2011 Functions Definition (Bracketing, Operator Precedence) I Parentheses are only given if necessary. I Operator precedence: A function call has a higher precedence than all other operators. I Arithmetic and logical operatores have usual priorities. I + - * / are left-associative. I Unary minus must be enclosed in parentheses: 1 * (-2) Algorithm: Haskell: Bracketing, Operator Precedence 1 2 3 4 5 6 7 8 9 −− F u n c t i o n A p p l i c a t i o n i n c r e m e n t 2 ∗ 10 ==> 30 i n c r e m e n t ( 2 ∗ 10) ==> 21 increment increment 2 ==> E r r o r increment ( increment 2) ==> 4 Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Values and Functions 51(112) April 15, 2011 Functions Algorithm: Haskell: Definition factorial function using two equations 1 2 fac_1 1 = 1 fac_1 n = fac_1 ( n−1) ∗ n Algorithm: Haskell: Definition factorial function using using case distinction 1 2 3 fac_2 n | n <= 1 = 1 | otherwise = fac_2 ( n−1) ∗ n Observation The call of the function fac_1 does not terminate for arguments < 1! Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Values and Functions 52(112) April 15, 2011 The First Self-Written Haskell Function Greatest Common Divisor Input Two different positive integers n and m. Output The (gcd) (gcd) of n and m. Algorithm E UCLID’s algorithm using subtraction: 1. Let n, the larger of the two numbers; if not interchange n and m. 2. Assign n := n − m 3. Compare the numbers n and m: 3.1 If n and m are not equal, then proceed with step 1. 3.2 If they are equal then terminate the algorithm: this number is the greatest common divisor. Algorithm: Haskell: gcd n m 1 2 3 4 6 7 −− E u c l i d ’ s a l g o r i t h m : n and m are p o s i t i v e numbers gcd_sub n m | n == m = n −− base o f t h e r e c u r s i o n | n > m = gcd_sub ( n−m) m −− r e c u r s i o n | otherwise = gcd_sub (m−n ) n −− r e c u r s i o n −− Note : t h e name gcd i s a p r e d e f i n e d f u n c t i o n −− C a l l : gcd_sub 30 12 ==> 5 Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Values and Functions 53(112) April 15, 2011 Using the Interpreter: ghci Algorithm: Haskell: Definition of the factorial function in file fac.hs 1 2 3 fac n | n <= 1 = 1 | otherwise = f a c ( n−1) ∗ n Invocation of the interpreter: > ghci fac.hs GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. [1 of 1] Compiling Main ( fac.hs, interpreted ) Ok, modules loaded: Main. *Main> fac 5 120 *Main> :load fac.hs [1 of 1] Compiling Main ( fac.hs, interpreted ) Ok, modules loaded: Main. *Main> Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Compiler & Interpreter: ghc / ghci 54(112) April 15, 2011 Using the Interpreter: ghci Commands of the ghci-interpreter Invocation of the interpreter: ghci file Command :help statement : :{\n... lines ...\n:}\n :type expr :info name :load file :break name :!Shell-Command :quit Arrow keys Meaning Show some help text Evaluate statement Repeat the last command Multi-line command Show the type of zhe expression expr Show some information about name Load file Place a breakpoint for the function name Execute Shell-Command Quit the session Show and edit the commands given last Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Compiler & Interpreter: ghc / ghci 55(112) April 15, 2011 Simple Data Types Definition (Tuple) I The data type tuple is defined by a the cartesian (cross) product of one or several other types: T1 × T2 × · · · × Tn I Elements of a tuple are noted within parentheses: (e1 , e2 , . . . , en ) where ei ∈ Ti . Algorithm: Haskell: Tupel 3 −− A f u n c t i o n may have a t u p l e as argument ( s ) sum_prod ( x , y ) = −− as w e l l as r e t u r n i n g i t as r e s u l t : ( x+y , x∗y ) 5 −− C a l l : 7 −− Access o f p a r t s o f an t u p l e : my_fst ( x , y ) = x −− r e t u r n s t h e f i r s t element o f t h e t u p l e my_snd ( x , y ) = y −− r e t u r n s t h e second element 1 2 8 9 sum_prod ( 2 , 3 ) ==> ( 5 , 6 ) Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 56(112) April 15, 2011 User Defined Data Types Definition (User Defined Data Type) The keyword data introduces the definition of a user defined data type syntactically. 1 2 3 data Name = C o n s t r u c t o r | C o n s t r u c t o r Type . . . . .... I A constructor creates a value with that name (Constructor). I Constructors may have parameters using tuples specified by the given Types. I Constructors implicitly define functions. I The names of the data type and the constructors must begin with a capital letter. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 57(112) April 15, 2011 User Defined Data Types Definition (Enumeration Type) An enumeration defines a finite set of values, which are named by the given identifiers. Algorithm: Haskell: enumeration data type Day, and a function nextDay using it 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 data Day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday −− Determine t h e n e x t weekday : nextDay Monday = Tuesday −− read : t h e day f o l l o w i n g Mo. i s Tu . nextDay Tuesday = Wednesday nextDay Wednesday = Thursday nextDay Thursday = F r i d a y nextDay F r i d a y = Saturday nextDay Saturday = Sunday nextDay Sunday = Monday Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 58(112) April 15, 2011 User Defined Data Types Algorithm: Haskell: a user defined data type Shape 1 2 3 4 5 data Shape = | | | | Rectangle F l o a t F l o a t C i r c l e Float E l l i p s e Float Float T r i a n g l e Float Float Polygon [ ( Float , F l o a t ) ] Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 59(112) April 15, 2011 User Defined Data Types Definition (Recursive Data Type) A recursive data type has in its definition a self-reference. Definition (List) A list of items is either 1. empty, i. e. it contains no elements; or 2. a list consists of a “first element”, named head and the “rest of the list”, named tail of the list. Algorithm: Haskell: recursive data type (list of numbers: IntList) 1 2 4 5 6 7 8 data I n t L i s t = N i l | Cons I n t I n t L i s t −− N i l : Not I n L i s t −− Cons : L i s t −C o n s t r u c t o r −− N i l and Cons are c o n s t r u c t o r s −− N i l c o n t r u c t o r has no arguments −− Cons t a k e s two arguments : −− a number ( o f t y p e I n t ) −− a l i s t ( w i t h t h e t y p e I n t L i s t d e f i n e d here ) Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 60(112) April 15, 2011 User Defined Data Types Definition (Binary Tree) A binary tree of items is either 1. empty, i. e. it contains no elements and is called a leaf ; or 2. a tree consists of a node , which has two children which are itself trees. Algorithm: Haskell: recursive data type (binary tree of numbers: IntTree) 1 2 data I n t T r e e = Leaf | Node I n t I n t T r e e I n t T r e e −− has no c h i l d r e n −− ( i n n e r ) node Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 61(112) April 15, 2011 User Defined Data Types Definition (Value Constructor) A value constructor is a function, which creates a value of the constructor’s data type. Value constructors may have arguments. Algorithm: Haskell: value constructors 1 2 −− Value o f t h e data t y p e Day Monday 4 5 6 7 8 −− Values o f t h e t y p e IntList Nil Cons 1 N i l Cons 1 ( Cons 2 N i l ) Cons 1 ( Cons 2 ( Cons 3 N i l ) ) 10 11 12 13 14 15 16 −− Values o f t h e t y p e IntTree Leaf Node 1 Leaf Leaf Node 1 ( Node 2 Leaf Leaf ) Leaf −− Node 1 −− / \ −− Node 2 Leaf −− / \ −− Leaf Leaf Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 62(112) April 15, 2011 Functions over Recursive Data Types Definition (Function Definition based on (recursive) Data Types) In the head of a function definition I a formal parameter, or I a value constructor of a given data type may be given. Definition (Function Evaluation based on (recursive) Data Types) Semantics of the evaluation a function: I The equations defining the function are “checked” in their textual order. I If the passed actual parameter matches the pattern given as formal parameter of an equation, the right hand side of the equation defines the result of this function call. I The patterns may be arbitrary complex. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 63(112) April 15, 2011 User Defined Data Types Algorithm: Haskell: a user defined data type Shape and the function area 1 2 3 4 5 7 8 9 10 11 12 13 15 16 data Shape = | | | | Rectangle F l o a t F l o a t C i r c l e Float E l l i p s e Float Float T r i a n g l e Float Float Polygon [ ( Float , F l o a t ) ] −− compute t h e area o f t h e Shape : area : : Shape −> F l o a t area ( Rectangle h e i g h t w i d t h ) = h e i g h t ∗ w i d t h area ( C i r c l e diameter ) = diameter ∗ diameter ∗ pi / 4 area ( E l l i p s e height width ) = height ∗ width ∗ pi / 4 area ( T r i a n g l e h e i g h t w i d t h ) = h e i g h t ∗ width / 2 area ( Polygon list ) = 0 −− more complex f o r m u l a −− A p p l i c a t i o n −− area ( C i r c l e 1 ) ==> 0.7853982 Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 64(112) April 15, 2011 Functions over Recursive Data Types Algorithm: Haskell: length of a list: length_IntList 1 2 data I n t L i s t = N i l | Cons I n t I n t L i s t 4 5 length_IntList Nil = 0 l e n g t h _ I n t L i s t ( Cons number l i s t ) = 1 + l e n g t h _ I n t L i s t list Algorithm: Haskell: Calling length_IntList 1 2 3 4 5 6 length_IntList Nil ==> 0 l e n g t h _ I n t L i s t ( Cons 1 N i l ) ==> 1 l e n g t h _ I n t L i s t ( Cons 1 ( Cons 2 N i l ) ) ==> 2 Algorithm: Haskell: sum_IntList: Sum of all elements of an IntList 1 2 3 4 5 6 sum_IntList Nil = 0 s u m _ I n t L i s t ( Cons number l i s t ) = number + s u m _ I n t L i s t l i s t −− C a l l i n g t h e f u n c t i o n w i t h i n t h e I n t e r p r e t e r s u m _ I n t L i s t Cons 1 ( Cons 2 ( Cons 3 N i l ) ) ==> 6 Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 65(112) April 15, 2011 Functions over Recursive Data Types Algorithm: Haskell: Sum of all nodes in a tree binary: sum_t 1 2 data I n t T r e e = Leaf | Node I n t I n t T r e e I n t T r e e 4 5 −− sum o f t h e numbers i n a l l nodes sum_t Leaf = 0 −− t h e empty t r e e 7 8 9 10 −− The sum o f a −− t h e number −− sum o f i t s −− sum o f i t s 12 sum_t ( Node number l e f t r i g h t ) = number + sum_t l e f t + sum_t r i g h t 14 15 16 17 18 −− o r u s i n g a n o t h e r s y n t a x : sum_t2 t r e e = case ( t r e e ) of Leaf −> 0 ( Node number l e f t r i g h t ) −> number + sum_t2 l e f t + sum_t2 r i g h t 20 21 22 23 24 −− C a l l o f t h e f u n c t i o n s : −− sum_t ( Node 1 Leaf Leaf ) 1 −− ==> −− sum_t ( Node 1 ( Node 2 Leaf Leaf ) Leaf ) 3 −− ==> tree is g i v e n i n t h e node p l u s " l e f t " children plus " right " children . Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 66(112) April 15, 2011 Lists Definition (Built in Syntax for Lists) To represent lists a special syntax is used in Haskell: I [ ] constructor for the empty list. I : constructor a list element, consisting of a data item and a list. I head : tail value constructor I All data elements of the list must have the same type. I The :-operator is right-associative 1:2:3:[] has to read as 1:(2:(3:[])). Example (Lists) 1:[] ⇒“list with one element” 1:2:[] ⇒“list with two elements” 1:2:3:[] ⇒“list with three elements” [1, 2, 3] ⇒“list with three elements” Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 67(112) April 15, 2011 Lists Algorithm: Haskell: functions over lists (length, sum, append, reverse) 1 2 3 5 6 7 9 10 11 13 14 15 16 18 19 20 −− l e n g t h o f a l i s t my_length [ ] = 0 my_length ( hd : t l ) = 1 + my_length t l −− ( hd = head , t l = t a i l ) −− sum over a l l l i s t elements my_sum [] = 0 my_sum ( hd : t l ) = hd + my_sum t l −− append an element a t t h e end o f a l i s t my_append x [ ] = x:[] my_append x ( hd : t l ) = hd : ( my_append x t l ) −− r e v e r t i n g a l i s t −− Idea: “append hd at the end of the reverted list tl.” my_reverse [ ] = [] my_reverse ( hd : t l ) = my_append hd ( my_reverse t l ) −− f u n c t i o n c a l l −− my_reverse [ 1 , 2 , 3 ] −− ==> [ 3 , 2 , 1 ] Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 68(112) April 15, 2011 Data Type (Signature) of Functions Definition (Data Type (Signature) of Functions) I A function with only one argument and one result has the data type 1 I T1 −> T2 If the function has more than one argument, it is written using the Curry-notation: 1 T1 −> T2 −> T3 −> · · · −> Tn Note: the → operator is right-associative: T1 → T2 → T3 → · · · → Tn has to be read as: (T1 → (T2 → (T3 → · · · (Tn−1 → Tn ) · · · ))) Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 69(112) April 15, 2011 Data Type (Signature) of Functions Notes I The Haskell data type T1 → T2 → T3 → · · · → Tn is semantically equivalent to the usual mathematics notation: T1 × T2 × . . . Ti →Ti+1 × Ti+2 × · · · × Tn Haskell does not specify, which arguments are input and output arguments. I Haskell, however, regards that mathematical type definition as the type of a function with only one input and one output parameter, but both are tuples! 1 (T1 , T2 , . . . , Ti ) −> (Ti+1 , Ti+2 , . . . , Tn ) Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 70(112) April 15, 2011 Data Type (Signature) of Functions Algorithm: Type of a function 1 2 4 5 7 8 10 11 13 14 15 17 18 f : : I n t −> I n t −> I n t f x y = x + y : type f f : : I n t −> I n t −> I n t : type f 1 2 f 1 2 : : Int : type f 1 f 1 : : I n t −> I n t g = f 1 : type g g : : I n t −> I n t g 2 ==> 3 Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 71(112) April 15, 2011 Data Type (Signature) of Functions Definition (Partial Evaluation, η-Reduction) Let f be a function f :: T1 → T2 → · · · → Tn → T with n arguments. If f is evaluated with m < n actual parameters, then result is a function f 0 :: Tm+1 → · · · → Tn → T which takes only n − m parameters. This is called a partial evaluation of a function. In mathematics that is named as η-reduction (eta-reduction). Algorithm: Example of partial evaluated functions 1 2 4 5 6 (+1) (^2) −− −− Increment Square −− c a l l i n g such f u n c t i o n s : (+1) 2 −− ==> 3 Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 72(112) April 15, 2011 User Defined Data Types Problem: 1 2 3 4 data I n t L i s t = | data F l o a t L i s t | Nil IntCons I n t I n t L i s t = Nil FloatCons F l o a t F l o a t L i s t Definition (Type Variables, Polymorphs Data Types) I Type variables are place holders for data types, which may occur in user defined data types. I Types using in their definition type variables are named polymorph types. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 73(112) April 15, 2011 User Defined Data Types Algorithm: Haskell: a polymorph list and a function operating on it (my_length) 1 2 4 5 7 8 10 11 12 data C o n s L i s t t = N i l | Cons t ( C o n s L i s t t ) −− t i s a t y p e v a r i a b l e −− my_length determines t h e l e n g t h o f a l i s t my_length : : C o n s L i s t t −> I n t −− Type o f t h e f u n c t i o n my_length N i l = 0 my_length ( Cons hd t l ) = 1 + my_length t l −− c a l l i t : −− my_length −− ==> 3 ( Cons 3 ( Cons 2 ( Cons 1 N i l ) ) ) Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 74(112) April 15, 2011 User Defined Data Types Algorithm: Haskell: a polymorph list and a function operating on it (my_add) 1 2 4 5 6 7 data C o n s L i s t t = N i l | Cons t ( C o n s L i s t t ) −− should add a l l v a l u e s o f t y p e t , e . g . I n t , i n t h e l i s t my_add : : C o n s L i s t t −> t my_add N i l = 0 my_add ( Cons hd t l ) = hd + my_add t l Outcome of ghci when compiling my_add [1 of 1] Compiling Main ( error-func-cons-list-sum.hs, interpreted ) error-func-cons-list-sum.hs:6:24: Could not deduce (Num t) from the context () arising from the literal ‘0’ at error-func-cons-list-sum.hs:6:24 Possible fix: add (Num t) to the context of the type signature for ‘my_add’ In the expression: 0 In the definition of ‘my_add’: my_add Nil = 0 Failed, modules loaded: none. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 75(112) April 15, 2011 User Defined Data Types Type System I I I I Haskell’s type system determines facts about types used in functions my_add Nil = 0 therefore the function returns a number. my_add (Cons hd tl) = hd + my_add tl therfore hd must be a number, but that’s not specified in the function’s type. Type classes, as shown below, will help to solve these problems. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 76(112) April 15, 2011 Generalization of Types Definition (Type Class) Comparable to object oreiented programming languages, Haskell provides the concept of type clases. I A type class defines functions and their types, which must be provided by all instances of that type class. I A type class my restrict properties of their type instances. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 77(112) April 15, 2011 78(112) April 15, 2011 Generalization of Types Definition (Type Class Eq ) The standard type class Eq is defined as: 1 2 1 2 3 class Eq a where ( = = ) , ( / = ) : : a −> a −> Bool instance Eq ( Float , F l o a t ) where ( x , y ) == ( u , v ) = x == u && y == v v1 / = v2 = not ( v1 == v2 ) Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types Generalization of Types Algorithm: Haskell: Polymorphic definition of list equality as instance of the type class Eq 1 2 3 4 5 instance Eq t => Eq [ t ] where [ ] == [ ] = True [ ] == _ = False ( x : xs ) == ( y : ys ) | x == y = xs == ys | otherwise = False Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 79(112) April 15, 2011 Generalization of Types Inhertiance Haskell provides the concept of inhertiance as known from object oreinted languages. In the following example, the type class Ord inherits properties and operators from the super class Eq. 1 2 class Eq a => Ord a where ( < ) , ( <=) , ( >=) , ( > ) : : a −> a −> Bool Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 80(112) April 15, 2011 Generalization of Types Definition (Standard Type Classes) Haskell provides many standard type classes, the most important are: Class Operations on the elements of instance types Eq Values are comparable on equality == and inequality /= Ord Values are totally orderd and may be compared using <, <=, >, >= Instances of Ord must also be instances of Eq Enum Privides the syntax notation of value intervals [a..b]. Instances of Enum must also be instances of Ord Num Values represent numbers (e.g. Int, Float). Arithmetic operatores are defined for them. Show Values may be converted automatically to strings, e.g. for output. Read Strings may be converted automatically to values (e.g. for input). Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 81(112) April 15, 2011 Data Types: Summary Definition (Data Type) A data type is a set of values together with operations and properties on the values. Definition (Type Constructors) A type constructor is a “statement” of a programming language which is used to create new data types from already given data types. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 82(112) April 15, 2011 Data Types: Summary Type Constructors in Haskell Synonym defines another name for a type 1 type T = . . . Tupel, cartesian product mathematically: T1 × T2 × · · · × Tn 1 2 type T = ( T1 , T2 , . . . , Tn ) −− named t y p l e data t y p e (e1 , e2 , . . . , en ) −− a t u p l e v a l u e c o n s t r u c t o r Union type mathematically: T1 ∪ T2 ∪ · · · ∪ Tn 1 2 3 4 5 data T = | | | Ti x y z T1 X Y Z . . . −− d e f i n i t i o n T2 . . . ... Tn . . . −− v a l u e c o n s t r u c t o r w i t h parameters Calling a value constructor Ti x y z which is parameterized with values x ∈ X , y ∈ Y , z ∈ Z , ... creates a value of type Ti Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 83(112) April 15, 2011 Data Types: Summary Type Constructors in Haskell List, [T] mathematically: T ∗ 1 2 [T] −− d e f i n i t i o n [e1 , e2 , . . . , en ] −− v a l u e c o n s t r u c t o r o f a l i s t w i t h n elements Function type, T1 → T2 mathematically a function with domain T1 and codomain T2 1 2 3 f : : T1 −> T2 f x = ....... −− d e f i n i t i o n −− I m p l e m e n t a t i o n by g i v i n g e q u a tu i o n s −− w i t h p a t t e r n matching Polymorphic types instead of a type a type variable may be used 1 2 type A s s o c i a t i v e L i s t a b = [ ( a , b ) ] −− a and b are t y p e v a r i a b l e s Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 84(112) April 15, 2011 Data Types: Summary Type Constructors in Haskell Type classes 1 2 3 4 class Eq a where ( = = ) : : a −> a −> Bool ( / = ) : : a −> a −> Bool x / = y = not ( x == y ) 5 6 7 8 9 10 11 13 14 15 17 18 19 −− −− −− −− == i s an overloaded o p e r a t o r a i s a type v a r i a b l e an a b s t r a c t i m p l e m e n t a t i o n o f /= u s i n g == −− Extending a t y p e : data T = ... ... d e r i v i n g Eq −− now T i n h e r i t s t h e o p e r a t o r s and −− f u n c t i o n s d e f i n e d by Eq −− I m p l e n t i n g t h e o p e r a t i o n s o f T instance Eq T where x == y = . . . . . −− R e s t r i c t i o n s on t h e t y p e v a r i a b l e s t1 f : : Eq t 1 => t 1 −> t 2 −− t1 has t o be a member −− o f t h e t y p e c l a s s Eq Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 85(112) April 15, 2011 Predefined Functions and Operators for Lists Algorithm: Haskell:Predefined Functions and Operators for Lists (head, tail, ++) 1 2 3 4 5 7 8 9 11 12 13 14 −− Head o f a l i s t head : : [ t ] −> t head ( hd : t l ) = hd −− Note : −− head [ ] r e s u l t s in a runtime e r r o r −− T a i l o f a l i s t t a i l : : [ t ] −> [ t ] t a i l ( hd : t l ) = t l −− Concatenation o f l i s t s ( + + ) : : [ t ] −> [ t ] −> [ t ] [ ] ++ list = list ( hd : t l ) ++ l i s t = hd : ( t l ++ l i s t ) 17 −− A p p l i c a t i o n o f t h e o p e r a t o r s and f u n c t i o n s [ 1 , 2 , 3 ] ++ [ 3 , 4 , 5 ] −− => [ 1 , 2 , 3 , 3 , 4 , 5 ] 19 head ( [ 1 , 2 , 3 ] ++ [ 3 , 4 , 5 ] ) −− => 1 21 t a i l ( [ 1 , 2 , 3 ] ++ [ 3 , 4 , 5 ] ) −− => [ 2 , 3 , 4 , 5 ] 16 Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 86(112) April 15, 2011 Predefined Functions and Operators for Lists A B C Algorithm: Haskell: Tower of Hanoi using lists 1 2 3 5 6 8 9 10 11 12 14 15 move [ from to ] −− hanoi : : count hanoi : : I n t −> [ ( Char , Char ) ] hanoi ( n ) = moveit ( n , ’ B ’ , ’ A ’ , ’C ’ ) [ ( Char , Char ) ] moveit : : ( I n t , Char , Char , Char ) −> −− count from t o helper move from t o moveit ( 0 , _ , _ , _ ) = [ ] moveit ( n , from , to , u s i n g ) = moveit ( n − 1 , from , using , t o ) ++ [ ( from , t o ) ] ++ moveit ( n − 1 , using , to , from ) −− c a l l : hanoi 3 −− r e s u l t s i n : [ ( 1 , 3 ) , ( 1 , 2 ) , ( 3 , 2 ) , ( 1 , 3 ) , ( 2 , 1 ) , ( 2 , 3 ) , ( 1 , 3 ) ] Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Data Types 87(112) April 15, 2011 Higher Order Functions Definition (Functions are Values) Funktionen are values an may be I passed as actual arguments to other functions; I the result of evaluating an expression. In imperative languages that concept is known under the name function pointer. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Functions as Values 88(112) April 15, 2011 Higher Order Functions Algorithm: Haskell: Functions as values (twice) 1 2 3 5 6 7 8 −− Apply a f u n c t i o n t w i c e onto an argument : t w i c e _ s i m p l e : : ( t −> t ) −> t −> t twice_simple f x = f ( f x ) fac fac | | : : I n t −> I n t −− compute t h e f a c t o r i a l number n n <= 1 = 1 otherwise = f a c ( n−1) ∗ n 10 11 12 −− Apply fac onto t h e r e s u l t o f fac : −− t w i c e _ s i m p l e f a c 3 −− ==> 720 14 15 16 −− t w i c e r e t u r n s a new f u n c t i o n ( new s y n t a x ) : t w i c e : : ( t −> t ) −> ( t −> t ) −− Note : t h e d i f f e r e n t t y p e twice f = f . f 18 19 20 −− c a l l i t : −− t w i c e f a c 3 −− ==> 720 22 23 −− what ’ s about : −− twice ( fac 3) ???? Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Functions as Values 89(112) April 15, 2011 Higher Order Functions Algorithm: Haskell: Applying a function to all elements of a list (map, filter) 1 2 3 5 6 7 9 10 11 12 14 15 16 18 19 21 22 map : : ( a −> b ) −> [ a ] −> [ b ] map f [ ] = [] map f ( hd : t l ) = f hd : map f t l −− Example : square a l l elements o f a l i s t map ( ^ 2 ) [ 1 , 2 , 3 , 4 ] ==> [ 1 , 4 , 9 , 1 6 ] f i l t e r : : ( t −> Bool ) −> [ t ] −> [ t ] filter f [] = [] f i l t e r f ( hd : t l ) | f hd = hd : f i l t e r f t l | otherwise = f i l t e r f t l −− Example : remove a l l even numbers o f a l i s t f i l t e r odd [ 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ==> [ 1 , 3 , 5 , 7 ] −− Example x 4 f o r each element x o f a l i s t : square_square l i s t = map ( t w i c e ( ^ 2 ) ) l i s t square_square [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 1 0 ] ==> [1 ,16 ,81 ,256 ,625 ,1296 ,2401 ,4096 ,6561 ,10000] Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Functions as Values 90(112) April 15, 2011 Haskell-Syntax Definition (If-expresssion) 1 2 3 if ... then . . . else . . . 4 5 6 7 8 9 −− Example : min a b = i f then else −− r e t u r n s t h e a < b a b s m a l l e r o f both v a l u e s Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Some Algorithms over Lists 91(112) April 15, 2011 92(112) April 15, 2011 Search the Minimum in a list Algorithm: Haskell: Search the minimum in a list 1 2 3 4 5 7 m i n _ l i s t : : Ord t => [ t ] −> t min_list [ x ] = x m i n _ l i s t ( hd : t l ) = i f hd < m i n _ l i s t t l then hd else m i n _ l i s t t l −− C a l l : m i n _ l i s t [ 9 , 1 , 3 , 2 ] Algorithm: Haskell: Search the minimum in a list, simlyfied by using let 1 2 3 4 5 6 8 m i n _ l i s t : : Ord t => [ t ] −> t min_list [ x ] = x m i n _ l i s t ( hd : t l ) = l e t t l _ m i n = m i n _ l i s t t l in if hd < t l _ m i n then hd else t l _ m i n −− C a l l : m i n _ l i s t [ 9 , 1 , 3 , 2 ] Time complexity of the algorithm is O(n2 ). Why? Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Some Algorithms over Lists Search the Minimum in a list Algorithm: Haskell: Search the minimum in a list (linear time complexity) 1 2 3 5 6 7 8 9 11 m i n _ l i s t : : Ord t => [ t ] −> t min_list [ x ] = x m i n _ l i s t ( hd : t l ) = m i n _ l i s t 1 hd t l m i n _ l i s t 1 : : Ord t => t −> [ t ] −> t min_list1 x [ ] = x m i n _ l i s t 1 x ( hd : t l ) = i f x < hd then m i n _ l i s t 1 x t l else m i n _ l i s t 1 hd t l −− C a l l : m i n _ l i s t [ 9 , 1 , 3 , 2 ] Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Some Algorithms over Lists 93(112) April 15, 2011 Sorting Algorithm: Insertion Sort I Function: insertIntoList element list Add an “element” into an already sorted “list”, so that the resulting list remains sorted. I Function: iSort list Sort the (unsorted) “list” by: 1. start with L the list empty, it’s already sorted; 2. use insertIntoSortedList to add the elements of the unsorted “list” into an already sorted result list L. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Some Algorithms over Lists 94(112) April 15, 2011 Sorting Algorithm: Haskell: polymorphic sorting of a list: insertion sort 1 2 3 4 5 7 8 10 11 12 14 15 i n s e r t I n t o L i s t : : Ord t => t −> [ t ] −> [ t ] insertIntoList e [] = [e] i n s e r t I n t o L i s t e ( hd : t l ) | e < hd = e : hd : t l | otherwise = hd : i n s e r t I n t o L i s t e t l −− c a l l : −− i n s e r t I n t o L i s t 7 [ 2 , 3 , 6 , 9 ] i S o r t : : Ord t => [ t ] −> [ t ] iSort [ ] = [] i S o r t ( hd : t l ) = i n s e r t I n t o L i s t hd ( i S o r t t l ) −− c a l l : −− i S o r t [ 1 0 , 8 , 4 , 1 , 2 , 3 ] Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Some Algorithms over Lists 95(112) April 15, 2011 Sorting Algorithm: Quicksort Input A listeL of items, which may be compared pairwise. Output A sorted list L0 , consisting of the elements of L. Method 1. The empty list is already sorted 2. Otherwise: 2.1 Chose an element p from L, the so called pivot element. 2.2 Partition L into two sub lists Lleft and Lright , so that I I all elements of Lleft are ≤ p. all elements of Lright are > p. 2.3 Sort Lleft and Lright . 2.4 The result list L0 is the concatenation of Lleft , p, Lright . Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Some Algorithms over Lists 96(112) April 15, 2011 Sorting Algorithm: Haskell: Quicksort 1 2 3 4 5 7 8 q u i c k s o r t : : Ord t => [ t ] −> [ t ] quicksort [ ] = [] q u i c k s o r t ( hd : t l ) = q u i c k s o r t ( f i l t e r ( < hd ) t l ) ++ [ hd ] ++ q u i c k s o r t ( f i l t e r ( >= hd ) t l ) −− C a l l : quicksort [4 ,8 ,1 ,10 ,1 ,22 ,0 ,22] −− ==> [ 0 , 1 , 1 , 4 , 8 , 1 0 , 2 2 , 2 2 ] Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Some Algorithms over Lists 97(112) April 15, 2011 Syntax Definition (Let-expression, Where-Clauses) Haskell allows the declaration of local names, which are valid only within a function. The keyword let defines a name in the expression: 1 2 3 l e t n1 = . . . . n2 = . . . . i n . . . n1 . . . . n2 . . . The keyword where is part of the syntax of a function definition and case expressions: 1 f . . . = . . . n1 . . . . n2 . . . where n1 = . . . . n2 = . . . . f ... 2 3 5 6 7 8 | . . . n1 . . . = . . . n2 . . . | . . . n1 . . . = . . . n2 . . . where n1 = . . . . n2 = . . . . Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Some Algorithms over Lists 98(112) April 15, 2011 Quicksort using the new syntax Algorithm: Haskell: Quicksort – more readable using let 1 2 3 4 5 6 7 q u i c k s o r t : : Ord t => [ t ] −> [ t ] quicksort [ ] = [] q u i c k s o r t ( hd : t l ) = l e t p i v o t = hd l e f t = quicksort ( f i l t e r (< pivot ) t l ) r i g h t = q u i c k s o r t ( f i l t e r ( >= p i v o t ) t l ) i n l e f t ++ [ p i v o t ] ++ r i g h t Algorithm: Haskell: Quicksort – more readable using where 1 2 3 4 5 6 7 q u i c k s o r t : : Ord t => [ t ] −> [ t ] quicksort [ ] = [] q u i c k s o r t ( hd : t l ) = l e f t ++ [ p i v o t ] ++ r i g h t where p i v o t = hd l e f t = quicksort ( f i l t e r (< pivot ) t l ) r i g h t = q u i c k s o r t ( f i l t e r ( >= p i v o t ) t l ) Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Some Algorithms over Lists 99(112) April 15, 2011 Lazy Evaluation Question What does the following function compute? Algorithm: Haskell: the function bottom 1 2 4 5 −− D e f i n i t i o n : bottom = bottom −− C a l l bottom The call of bottom does not terminate! Definition (Bottom, ⊥ ) The “value” of a non-terminating expression is named bottom and is denoted by ⊥ . Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Lazy Evaluation 100(112) April 15, 2011 Lazy Evaluation Question What does the following functions compute? Algorithm: Haskell: using the function bottom 1 2 3 4 6 7 8 −− D e f i n i t i o n s : bottom = bottom f x = 1 g x = x −− C a l l s f 100 f bottom −− −− t e r m i n a t e s and r e t u r n s 1 t e r m i n a t e s and r e t u r n s 1 g 100 g bottom −− −− t e r m i n a t e s and r e t u r n s 100 does n o t t e r m i n a t e 10 11 Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Lazy Evaluation 101(112) April 15, 2011 Lazy Evaluation Definition (Strict, and Lazy Function evaluation) I A function f is named strict, if f ⊥ evaluates to ⊥. This means, that applying f to a non-terminating argument, f does terminate itself. I A function is named lazy (not strict), if f ⊥ is not equal to ⊥. With other words f ⊥ terminates. Note I In imperative programming languages (C, C++, Java), functions are always evaluated strictly. I Haskell allows the lazy evaluation of function arguments. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Lazy Evaluation 102(112) April 15, 2011 Lazy Evaluation Question What does the following functions compute? Algorithm: Haskell: using lazy evaluation 1 2 3 5 6 7 9 10 12 13 14 15 ones = 1 : ones −− C a l l ones −− doesn ’ t t e r m i n a t e and r e t u r n s a l i s t o f 1 numsFrom n = n : numsFrom ( n +1) −− C a l l numsFrom 5 −− doesn ’ t t e r m i n a t e and r e t u r n s l i s t o f numbers 5 , 6 , 7 , . . . −− S i m p l i f y t o : [5 . . ] −− doesn ’ t t e r m i n a t e and r e t u r n s l i s t o f numbers 5 , 6 , 7 , . . . squares = map ( ^ 2 ) [ 0 . . ] −− A u f r u f squares −− doesn ’ t t e r m i n a t e an r e t u r n s l i s t o f square numbers −− 0 , 1 , 4 , 9 , 16 , . . . Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Lazy Evaluation 103(112) April 15, 2011 Lazy Evaluation Question How can we get a finite slice from those infinite lists? Algorithm: Haskell: beginning of a list 1 2 3 5 6 7 9 10 11 13 14 16 17 −− I n p u t : a number n and a l i s t l −− Output : t h e l i s t c o n s i s t i n g o f t h e f i r s t n elements o f l my_take : : I n t −> [ t ] −> [ t ] my_take 0 _ = [] my_take _ [ ] = [] my_take n ( h : t ) = h : my_take ( n−1) t −− C a l l my_take 2 [ 1 , 2 , 3 , 4 ] ==> [ 1 , 2 ] my_take 10 [ 1 , 2 , 3 , 4 ] ==> [ 1 , 2 , 3 , 4 ] my_take 2 [ 1 . . ] ==> [ 1 , 2 ] why???? Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Lazy Evaluation 104(112) April 15, 2011 Lazy Evaluation Answer to the question How can we get a finite slice from those infinite lists? Algorithm: Haskell: List of the first n square numbers 1 2 3 = map ( ^ 2 ) [ 0 . . ] squares −− C a l l squares −− doesn ’ t t e r m i n a t e an r e t u r n s l i s t o f square numbers −− 0 , 1 , 4 , 9 , 16 , . . . 4 6 7 take 5 squares −− ==> [ 0 , 1 , 4 , 9 , 1 6 ] −− Terminates Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Lazy Evaluation 105(112) April 15, 2011 Lazy Evaluation Order of function equations Consider the following two definitions of take: 1 2 3 4 6 7 8 9 11 12 13 15 16 my_take1 : : my_take1 0 my_take1 _ my_take1 n I n t −> [ t ] −> [ t ] _ = [] [] = [] ( h : t ) = h : my_take1 ( n−1) t my_take2 : : my_take2 _ my_take2 0 my_take2 n I n t −> [ t ] −> [ t ] [] = [] _ = [] ( h : t ) = h : my_take2 ( n−1) t −− C a l l : my_take1 my_take2 0 bottom 0 bottom my_take2 my_take2 bottom [ ] bottom [ ] −− => −− => −− => −− => terminates with [ ] does n o t t e r m i n a t e does n o t t e r m i n a t e s terminates with [ ] Which implementation should be used for standard take? Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Lazy Evaluation 106(112) April 15, 2011 Lazy Evaluation The sieve of Eratosthenes 1. Write down all numbers 2, 3, 4, 5, 6, 7, ...n. 2. Remove from the list all multiples of 2. 3. Start from the beginning of the list and look for the first not yet considered number; remove all multiples of that numer from the list. 4. Continue with 3, as long as there are numbers not considered Algorithm: Haskell: The sieve of Eratosthenes 1 2 3 5 6 8 9 primes : : [ I n t ] primes = s i e v e [ 2 . . ] where s i e v e ( p : xs ) = p : s i e v e ( d e l e t e p xs ) d e l e t e : : I n t −> [ I n t ] −> [ I n t ] d e l e t e x xs = f i l t e r ( t e s t x ) xs t e s t : : I n t −> I n t −> Bool t e s t p x = x ‘mod‘ p / = 0 Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Lazy Evaluation 107(112) April 15, 2011 Lazy Evaluation Algorithm: Haskell: The sieve of Eratosthenes – shorter 1 2 3 primes : : [ I n t ] primes = s i e v e [ 2 . . ] where s i e v e ( p : xs ) = p : s i e v e [ x | x<−xs , x ‘mod‘ p / = 0 ] Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ Lazy Evaluation 108(112) April 15, 2011 More Topics I Still more syntax to simplify list handling I Overloading I Monadd I Input / Output I .... Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ And There is Still More ... 109(112) April 15, 2011 References I B ACKUS, John Warner [Aug. 1978]. Can Programming Be Liberated From the Von Neumann Style? A Functional Style and its Algebra of Programs. In: Communications of the ACM 16.8, pp. 613–641 [cit. on p. 7]. DAUMEÉ III, Hal [2002]. Yet Another Haskell Tutorial. Tech. rep. Yale University. URL: http://darcs.haskell.org/yaht/yaht.pdf [cit. on p. 47]. H UDAK, Paul, John P ETERSON, and Joseph H. FASEL [Oct. 1999]. A Gentle Introduction to Haskell 98. Tech. rep. Yale University. URL: http://www.haskell.org/tutorial [cit. on p. 47]. H UDAK, Paul, Simon P EYTON J ONES, and Philip WADLER [May 1992]. Report on the programming language Haskell: a non-strict, purely functional language version 1.2. In: ACM SIGPLAN Notices 27.5, pp. 1 –164. URL: http://www.haskell.org/haskellwiki/Language_and_library_specification [cit. on pp. 45, 47]. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ And There is Still More ... 110(112) April 15, 2011 References II H UGHES, John [1989]. Why Functional Programming Matters. In: Computer Journal 32.2, pp. 98–107. URL: http://www.cs.chalmers.se/\~rjmh/Papers/whyfp.html [cit. on p. 7]. L OUDEN, Kenneth C. [2002]. Programming Languages, Principles and Practice. 2nd ed. Thomson Press [cit. on p. 7]. M ARLOW, Simon [July 2002]. Developing a high-performance web server in Concurrent Haskell. In: Journal of Functional Programming 12.4+5, pp. 359–374. URL: http://www.haskell.org/~simonmar/papers/web-server-jfp.pdf [cit. on p. 7]. P EPPER, Peter [2003]. Funktionale Programmierung in OPAL, ML, HASKELL und GOPHER. 2nd ed. Springer Verlag, Heidelberg, New York [cit. on p. 3]. S ALUS, Peter H. [1998]. Functional and Logic Programming Languages. Vol. 4. Handbook of Programming Languages. Macmillan Technical Publishing, Indianapolis, Indiana [cit. on p. 7]. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ And There is Still More ... 111(112) April 15, 2011 References III S COTT, Michael L. [2009]. Programming Languages Pragmatics. 3rd ed. Morgan Kaufmann Publishers [cit. on p. 7]. S TEWART, Don and Spencer J ANSSEN [Sept. 2007]. XMonad: A Tiling Window Manager. In: Haskell ’07: Proceedings of the ACM SIGPLAN workshop on Haskell workshop, Freiburg Germany. URL: http://www.cse.unsw.edu.au/~dons/papers/haskell51d-stewart.pdf [cit. on p. 7]. T HIEMANN, Peter [2002]. WASH/CGI: Server-side Web Scripting with Sessions and Typed, Compositional Forms. In: Practical Aspects of Declarative Languages: 4th International Symposium, PADL 2002, volume 2257 of LNCS. Springer Verlag, Heidelberg, New York, pp. 192–208. URL: http://www.informatik.uni-freiburg.de/~thiemann/papers/padl02.pdf [cit. on p. 7]. W INSTON, Patrick Henry and Bertold Klaus Paul H ORN [1989]. LISP. 3rd ed. english edition. Addison-Wesley [cit. on p. 7]. Prof. Dr. Jürgen Vollmer: Introduction Functional Programming / Haskell/ And There is Still More ... 112(112) April 15, 2011