HASKELL PROGRAMMING AND stever/Haskell_notes.pdfFunctional Programming and Haskell StevedReeves 2006 University ofeWaikato 1 FUNCTIONAL PROGRAMMING AND HASKELL ... of elements in the list xs

Download HASKELL PROGRAMMING AND  stever/Haskell_notes.pdfFunctional Programming and Haskell StevedReeves 2006 University ofeWaikato 1 FUNCTIONAL PROGRAMMING AND HASKELL ... of elements in the list xs

Post on 13-May-2018

216 views

Category:

Documents

3 download

Embed Size (px)

TRANSCRIPT

<ul><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 1 </p><p>FUNCTIONAL </p><p>PROGRAMMING AND </p><p>HASKELL </p><p>SOME ELEMENTARY NOTES </p><p>Steve Reeves Department of Computer Science </p><p>University of Waikato </p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 2 </p><p>Many of these notes are based on </p><p>Haskell: The Craft of Functional Programming, Simon Thompson, Addison-Wesley, 1996 This introduction is based on chapter one of: </p><p> Functional Programming with Miranda, Ian Holyer, UCL Press, 1993 which is in the Library. </p><p>Other good books, all in the Library, on functional programming are: </p><p> Miranda: The Craft of Functional Programming, Simon Thompson, Addison-Wesley, 1995 Introduction to Functional Programming, Richard Bird and Philip Wadler, Prentice-Hall, 1988 </p><p> Elements of Functional Programming, Chris Reade, Addison-Wesley, 1989 </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 3 </p><p>Also, search the Library catalogues for functional programming - there are about 12 more books on the subject in our Library</p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 4 </p><p>Taxonomy </p><p> specification </p><p> declarative logical functional languages structured procedural high-level low-level</p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 5 </p><p>Procedural Languages </p><p> developed first in the 1950s </p><p> most languages today are procedural </p><p> two common ideas - instructions executed sequentially - values stored in locations brought together by defining sequences </p><p>of instructions to change the contents of storage - procedures, routines </p><p> these languages closely match the </p><p>architecture of most of today!s computers </p><p> - advantage is efficiency - disadvantage is unnecessary </p><p> detail</p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 6 </p><p>Evolution machine code low-level </p><p> assembly high-level ForTran, BASIC structured C, Pascal, Modula object-oriented Smalltalk </p><p> C++ </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 7 </p><p>Declarative Languages </p><p> origins in the !-calculus of 1930s </p><p> became practical in the 1970s at a higher-level than any of the </p><p>procedural languages breaks away from the procedural model allows expression of algorithms in a very </p><p>clear and direct way few unnecessary details values can be defined and manipulated </p><p>directly no need to worry about how or where </p><p>they are stored </p><p> algorithms are given by declaring </p><p>relationships between values - no concern about the order used </p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 8 </p><p> Various sorts of expressions declare </p><p>relations between values </p><p> Logic programming languages use </p><p>relations Specification languages use any </p><p>mathematical structures you like - they are more general and </p><p> expressive than either logic of functional languages </p><p> - so expressive that you can write </p><p> down relations that are not computable!! </p><p> Functional languages use functions </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 9 </p><p>Programming with Functions </p><p> Functional programming languages started in the 1980s (LISP started in the 1950s but is hybrid, i.e. combines functional and procedural features) languages like Miranda, Haskell and Gofer </p><p>are all very similar </p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 10 </p><p>Functions for Programming In a functional language, functions are the </p><p>basic building blocks from which programs are constructed </p><p> A program is a function from its inputs to </p><p>its output: </p><p>inputsprogram</p><p>output</p><p> This gives rise to two important </p><p>differences between functions and procedures: </p><p> functions have no side effects they can have no effect on the </p><p> world outside except to deliver a result value </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 11 </p><p> functions have no state they give the same result every </p><p> time they are evaluated with the same arguments </p><p> this means that functions form self-contained </p><p> units all their connections with the </p><p> outside world are explicit they are therefore safe and </p><p> convenient building blocks </p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 12 </p><p> two most common ways of combining functions </p><p> pass the results of one to the </p><p> arguments of another fourth_power n = square (square n) </p><p> pass a function as an argument to </p><p> another function </p><p> square_list ns = map square ns where map f [x1,x2,x3,...,xn] = [f x1, f x2,...,f xn] so square_list [1,2,3,4] = [1,4,9,16] </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 13 </p><p> map is an example of a very useful and common value in functional programming, the higher-order function </p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 14 </p><p>Gofer and Haskell They are lazy, polymorphic, purely </p><p>functional programming languages </p><p> Developed following the Haskell Report We shall be using HUGS-Haskell User!s </p><p>Gofer System-Available, free, for PCs (IBM-style and Macs), Ataris, Amigas, larger Unix machines and others </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 15 </p><p>Using HUGS In the labs we will be using HUGS running </p><p>under Linux </p><p> To run the interpreter just type hugs Typing :? will show you commands that can be </p><p>used :l will load a file called , which you </p><p>can fill with definitions, or a script, using any editor like emacs, vi or textedit (under X) </p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 16 </p><p> any definitions you load from a file will augment the standard definitions which are always available, so extending the set of expressions that can be evaluated </p><p> any expressions you type at the prompt ? </p><p>will be evaluated and their value printed as output: </p><p> ? 2 + 3 5 ? sum [1..10] 55 ? product [1..6] 720 </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 17 </p><p>Data Simple data or unstructured data - numbers </p><p> 42 :: Int i.e. 42 has type Int 3.14159 :: Fractional - operations on numbers (+) :: Int -&gt; Int -&gt; Int (+) 2 3 :: Int (+) 2 3 = 5 </p><p> more usually written 2 + 3, these forms are equivalent </p><p> (*),(-),(/),(^) and many more - characters a :: Char </p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 18 </p><p> 0 :: Char \n :: Char - operations ord :: Char -&gt; Int chr :: Int -&gt; Char ord a = 97 chr 65 = A - Booleans True :: Bool False :: Bool - operations (&amp;&amp;) :: Bool -&gt; Bool -&gt; Bool not :: Bool -&gt; Bool True &amp;&amp; True = True </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 19 </p><p> You can get HUGS to tell you the type of </p><p>expressions by typing :t ord for example, which will give the response ord :: Char -&gt; Int </p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 20 </p><p> Structured Data - Lists given a type t, values of type </p><p> [t] are lists whose elements have type t </p><p> [1,2,3,4] :: [Int] [a,b,c,d] :: [Char] [True, True, False] :: [Bool] [[1,2],[1,5],[1],[2,3]] :: [[Int]] </p><p> [] :: [Char] [] :: [Int] lists can also be written using </p><p> the constructor : [1,2,3] = 1 : 2 : 3 : [] </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 21 </p><p> = 1 : [2,3] = 1 : 2 :[3] :: [Int] </p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 22 </p><p> - operations length xs returns the number </p><p> of elements in the list xs xs ++ ys returns the list of </p><p> elements in xs followed by the elements in ys </p><p> map f xs returns the list </p><p> obtained by applying the function f to each of the elements of the list xs </p><p> length [1,2,3,4] = 4 length [a,b,c] = 3 [1,2] ++ [4,5] = [1,2,4,5] map ord [a,b] = [97, 98] </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 23 </p><p> - special lists [n..m] is the list of integers from n to m [3..5] = [3,4,5] The list with values of the form [n,n+k..m] is the list [n,n+k,n+2k,n+3k..n+dk,m] where </p><p> n+dk " m &lt; n + (d+1)k [1,3..11] = [1,3,5,7,9,11] [n..] is the list [n,n+1,n+2,n+3...] </p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 24 </p><p> i.e. no matter how many times you take away the first element, there is always more list - a sort of infinite list on numbers starting from n </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 25 </p><p> - tuples if t1, t2,..., tn (n#2) are types </p><p> then (t1, t2,...,tn) is the type of n-tuples of the form (x1,x2,...,xn) where x1 has type t1, x2 has type t2 and so on </p><p> (1, [2], 3) :: (Int, [Int], Int) (True,1,a) :: (Bool, Int, Char) </p><p> ((1,2),(0,1)) :: ((Int,Int),(Int,Int)) note that we can make lists and tuples of </p><p>any values, including the operations above </p><p> [(+),(-),(*)] :: [Int -&gt; Int] (ord,chr) :: (Char -&gt; Int, Int -&gt; Char) </p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 26 </p><p>Functions - consider a collection of definitions square :: Int -&gt; Int square n = n * n fourth_power :: Int -&gt; Int fourth_power n = square(square n) twice ::(Int -&gt; Int) -&gt; Int -&gt; Int </p><p> twice f x = f (f x) - in the definition of square </p><p> above, n is a formal parameter whose scope is the whole of the definition </p><p> - the scope of square is the </p><p> whole collection - functions with no arguments </p><p> are constant values </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 27 </p><p> - types are automatically calculated </p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 28 </p><p> Cases another important general way of defining </p><p>functions is to consider cases using guards </p><p> going back to factorial again, e could have said </p><p> fact :: Int -&gt; Int fact n | n == 0 = 1 | n &gt;= 0 = n * fact (n-1) here the expressions n == 0 and n &gt;= 0, which must always have type Bool, are called the guards </p><p> to evaluate such a definition we evaluate </p><p>the guards in turn until we find one that is True - in that case the corresponding expression on the right-hand side of the = sign is the value of the function </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 29 </p><p> for example we can define a function max which given two integers has the maximum of the two as its value </p><p> max :: Int -&gt; Int -&gt; Int max x y | x &gt;= y = x | y &gt;= x = y </p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 30 </p><p>Example (from Thompson) Assume we are given a function sales :: Int -&gt; Int which gives the weekly sales from a shop </p><p>for weeks numbered 0, 1, 2 etc. The task is to calculate the following: total sales for the period week 0 to week n the maximum weekly sale during weeks 0 </p><p>to n the week in which the maximum sale took </p><p>place whether there is a week between week 0 </p><p>and week n in which no sales took place a week between week 0 and week n in </p><p>which no sales took place (if there is such a week) </p><p> Consider the first of these. </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 31 </p><p> The total sales for the period week 0 to </p><p>week 2 is given by sales 0 + sales 1 + sales 2 </p><p>If we want this for every value of n, though we are asking for a function </p><p> totalsales :: Int -&gt; Int the total sales up to week 0 are just sales 0 the total sales up to week n where n &gt; 0 are sales 0 + sales 1 + sales 2 +...+ sales(n-1) + sales n </p><p>|_______________________| this is just the total sales up to week n-1 i.e. totalsales (n-1) </p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 32 </p><p>So totalsales n = totalsales (n-1) + sales n </p><p> Putting the two cases together gives totalsales n | n == 0 = sales 0 | n &gt; 0 = totalsales(n-1) + sales n e.g. if we have sales 0 = 7, sales 1 = 2 and sales </p><p>2 = 5 then totalsales 2 = totalsales 1 + sales 2 = totalsales 0 + sales 1 + sales 2 </p><p> = sales 0 + sales 1 + sales 2 = 7 + sales 1 + sales 2 = 7 + 2 + sales 2 = 9 + sales 2 = 9 + 5 = 14 </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 33 </p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 34 </p><p>Consider the second problem - finding the maximum weekly sale We want a function maxSales :: Int -&gt; Int where - the maximum sale in the weeks up to </p><p>week 0 must be sales 0 - when n&gt;0 the maximum weekly sale can </p><p>occur in two places either - in the weeks up to and including </p><p>week n-1 or - in week n </p><p>The maximum sale for the weeks up to week n-1 is maxSales(n-1) and we need to compare this with sales n to see which is the biggest and hence the value of maxSales n </p><p> We have maxSales n | n==0 = sales 0 </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 35 </p><p> | maxSales(n-1) &gt;= sales n = maxSales(n-1) | otherwise = sales n Recall the function max from page 23 </p><p>above, then we have the much nicer definition </p><p> maxSales n | n==0 = sales 0 | otherwise = max (maxSales(n-1)) (sales n) </p><p> In general there is a standard pattern for </p><p>definitions: </p><p> 1) give a value for the function at 0 this is the base case or starting </p><p> value 2) give a value for the function at n by </p><p>using the value at n-1 this is the recursive case</p><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 36 </p><p> Patterns in function definitions patterns provide an elegant and concise </p><p>way of defining functions </p><p> the cases which a function has to deal with are often suggested by the form of its arguments - patterns make this very clear </p><p> consider the factorial function fact n = n! = 1 * 2 * 3 * ... * n and fact 0 = 1 In Haskell, one way of writing this is fact :: Int -&gt; Int fact 0 = 1 fact (n+1) = (n+1) * fact n Given the expression fact 4 to evaluate </p><p>we use pattern matching to decide which equation in the definition to use </p></li><li><p>Functional Programming and HaskellSteve Reeves2006University of Waikato 37 </p><p> Clearly, fact 4 does not match fact 0 </p><p>since 4 and 0 cannot be made the same However, fact 4 can match fact (n+1) since if we substitute 3 for n, and we consider 4 to be 3 + 1, the expressions look the same, i.e. </p><p> fact (3+1) This means that we select the second </p><p>equation and so the evaluation for fact 4 proceeds by one step </p><p> fact 4 = (3 + 1) * fact 3 Again, we find one of the equations that </p><p>matches fact 3 - considering fact 3 as fact (2+1) means that the second equation again matches so we have </p><p> fact 4 = (3...</p></li></ul>