2010 03 21 Dan.vasicek.functional Programming Using Haskell

Download 2010 03 21 Dan.vasicek.functional Programming Using Haskell

Post on 28-Nov-2014

50 views

Category:

Documents

0 download

Embed Size (px)

TRANSCRIPT

<p>Functional Programming Using</p> <p>HaskellDan Vasicek 2010 03 21</p> <p>Functional Programming in Haskell Haskell Information Sources Fundamental concepts Functional Programming Sessions, modules, &amp; scripts Polymorphic types Order of evaluation Patterns Lazy evaluation Side Effects Fundamental Data types Boolian Numbers Characters Compound data types Tuples Lists User Defined Types oEnumerations Efficiency Evaluation order Lazy Evaluation Space Monads Examples</p> <p>Sources of Information Book - Introduction to Functional Programming Using Haskell , Richard Bird, Pearson Education Limited, England, Prentice Hall Europe 1998 Tutorial http://www.cs.utah.edu/~hal/docs/daume02y aht.pdf For writing real production code see: http://haskell.org/haskellwiki/How_to_write_a_ Haskell_program</p> <p>Three Haskell Systems HUGS Haskell Users Gofer System Interpreter only http://www.haskell.org/hugs Faster than ghc</p> <p> GHC Glasgow Haskell Compiler Both interpreter and compiler Slower , more complex, and bigger than hugs and nhc</p> <p> NHC - Nearly a Haskell Compiler Complier only http://www.haskell.org/nhc98/download.html</p> <p>Functional Programming A functional program is a function that solves a problem That function may involve several subsidiary functions and is described in a notation that obeys normal mathematical principles The result of the function is the solution of the problem and is disjoint from the input to the function As in mathematics, once a function is proven correct, changes in the environment will not invalidate your proof Functions can be passed as arguments and are first class Functions do not change the global state Single assignment. Once a variable gets a value, it never changes.</p> <p>Functional Programming in C Prohibit the use of pointers? Not likely! Careful use of pointers</p> <p> No modification of input parameters All output is clearly separated from the input Output = function_name(input) Subroutine_name (input; output)</p> <p>Fundamental Concepts of Haskell Polymorphic Static types length list The list can have elements of any type. So, length is polymorphic. It can be applied to lists of characters, numbers, tuples, lists, length [] =0 length (x:xs) = 1+ length xs Where [] is a pattern that means the empty list And x:xs is a pattern that means x is the first element of the input list and xs is the rest of the list ( : is the cons operator)</p> <p> Called pattern matching . And pattern matching is an important component of Haskell (more later)</p> <p>Examples of Polymorphism head head (x:xs) :: [a] -&gt; a = x</p> <p> tail :: [a] -&gt; [a] tail (x:xs) = xs Both fail if presented with an empty list Both work for lists of anything, even lists of empty lists and are Polymorphic Examples of the Hindley-Milner type system</p> <p>Order of Evaluation Order of evaluation (simplification, or reduction) is not specified in a functional program Define: sq x = x*x sq(3+4) could be simplified as sq(7) 7*7 49 (3+4)*(3+4) 7*(3+4) 7*7 49</p> <p> Both orders produce the same result The independence of the result from the order is a characteristic feature functional programs The OS is free to choose the best order</p> <p>Lazy Evaluation let three x = 3 let infinity = infinity +1 Now simplify the expression three infinity Simplification of infinity first gives Three(infinity +1 +1 +1 and so on) which does not terminate</p> <p> Simplification of three first, three infinity = 3 the expression terminates in one step</p> <p> Some simplification orders may terminate while others do not In GHCi three infinity =3 In general, some simplification orders will be more efficient than others</p> <p>Lazy Evaluation Guarantees termination whenever termination is possible Allows the OS to choose an efficient evaluation order</p> <p>Side Effects A side effect is essentially something that happens in the course of executing a function that is not related to the output produced by that function. A pure function simply returns a value A pure function has no internal state A pure function cannot modify the input data Given the same arguments a pure function will always produce the same result In GHCi values may be displayed by the interactive environment Monadic programming allows functional programs to mimic imperative programs Monads provide a way to execute Commands and display values</p> <p>Monads Haskell uses monads to isolate all impure (not functional) computations from the rest of the program and perform them in the safe way The execution order of a functional program is entirely determined by the operating system. And this applies to the order of execution of I/O as well Thus, the order of I/O can not be preserved by a functional program</p> <p>Example of Scrambled I/O Order Thus, the order of I/O can not be preserved by a functional program Suppose that your functional program wrote the words in the following order: be preserved a functional program the order of I/O can not by Thus,</p> <p>Imperative Constructs are NOT Functional x=x+1 is not allowed! All ghci commands are imperative. The interactive environment is imperative http://www.haskell.org/haskellwiki/Functional _programming http://www.haskell.org/all_about_monads/ht ml/class.html</p> <p>Haskell Fundamental Data Types Bool: True or False Char: a , '\n', '\x05e0 , \122 a newline z Number:1 2.718</p> <p>Compound Data types Tuples ( a , Daniel , 3.14159) is valid (1, map) is a valid tuple. But you will have to define an I/O Monad to Show it. The functions for extracting the first and second element of a pair are defined in the standard Haskell environment fst(x,y) = x snd(x,y) = y</p> <p> fst(1,2,3) is not defined in the standard environment</p> <p>Lists Lists a list is enclosed in square brackets The empty list is [] The cons operator is : 1:2:3:[] is [1,2,3] Daniel is D : a : n : i : e : l :[] =[ D , a , n , i , e , l ] D : an = Dan</p> <p> All elements of a list must be of the same type [[1,2],[1]] is a valid list</p> <p>Comments in Haskell Code Single line comments are preceded by ``--'' and continue to the end of the line. For example: suc n = n + 1 -- this is a successor function Multiline and nested comments begin with {and end with -}. Thus {- can be used to inactivate a block of code -}</p> <p>Literate Programming A literate code file is a file with suffix .lhs instead of .hs (Literate Haskell) Two styles for literate code: LaTeX Style : \begin{code} \end{code} Bird Style: prefix code lines with the &gt; character</p> <p> Compiler flags allow for reconfiguration of the literate style</p> <p>Example: LaTeX Literate StyleHere is a simple example of a literate script for defining the quicksort function: \begin{code}tsort [] = [] tsort (x:xs) = tsort [y | y Integer &gt; fact 0 = 1 &gt; fact n = n * fact (n-1) And a blank line is required after the code as well</p> <p>Emacs Supports a Multi Mode Display One style for LaTeX And a second style for Haskell http://www.haskell.org/haskellwiki/Literate_p rogramming#Haskell_and_literate_programmi ng</p> <p>Literate Programming in VIM http://www.haskell.org/haskellwiki/Literate_p rogramming/Vim</p> <p>Quick Sort Algorithmqsort [] = [] qsort ( x:xs) = qsort (filter (&lt; x) xs) ++ qsort (filter ( &gt;= x) xs) Inefficient! Calls filter twice for xs Can use (length (x:xs))2memory</p> <p>More Efficient quicksortqsort [] = [] qsort x:xs = qsort ys ++ [x] ++ qsort zs where (ys, zs) = partition (&lt; x) xs Avoids filtering xs twice Still can use n2 memory! Notice that the &lt; is necessary in the comparison to preserve the original order of identical elements</p> <p>User Defined Types Enumerated Types data Typename = Type1 | Type2| Type3</p> <p>Example of Enumerated Typemodule Color where data Color = Red | Orange | Yellow| Green| Blue| Purple | White | Black colorToRGB Red = (255,0,0) colorToRGB Orange = (255,128,0) colorToRGB Yellow = (255,255,0) colorToRGB Green = (0,255,0) colorToRGB Blue = (0,0,255) colorToRGB Purple = (255,0,255) colorToRGB White = (255,255,255) colorToRGB Black = (0,0,0)</p> <p>Example of Enumerated Types colorToRGB Red returns the value: (255,0,0) Red == Blue fails because == is not defined for type Color colorToRGB Red == colorToRGB Blue Returns the value False</p> <p>User Defined Types User defined data types are done via a ``data'' declaration having the general form: data T u1 ... un = C1 t11 ... t1k1 | ... | Cn tn1 ... Tnkn where T is a type constructor; the ui are type variables; the Ci are (data) constructors; and the tij are the constituent types (possibly containing some ui). The presence of the ui implies that the type is polymorphic --- it may be instantiated by substituting specific types for the ui</p> <p>User Defined Types data Bool = True | False Bool is the type constructor True and False are the data constructors</p> <p> data Color = Red | Green | Blue | Indigo data Point a = Pt a a a on the lhs is a type variable</p> <p> data Tree a = Branch (Tree a) (Tree a) | Leaf a a is a constituent type on the rhs</p> <p>Type Synonyms General Definition Unknown (examples only) type String = [Char] type Person = (Name, Address) type Name = String data Address = None | Addr String</p> <p>Pythagorian Triadsmodule PythagorianTriads where triples :: Int -&gt; [(Int, Int, Int)] triples n = [(x, y, z) | x </p>