# 2010 03 21 dan.vasicek.functional programming using haskell

Post on 28-Nov-2014

50 views

Category:

## Documents

Embed Size (px)

TRANSCRIPT

Functional Programming Using

Functional Programming in Haskell Haskell Information Sources Fundamental concepts Functional Programming Sessions, modules, & 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

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

GHC Glasgow Haskell Compiler Both interpreter and compiler Slower , more complex, and bigger than hugs and nhc

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.

Functional Programming in C Prohibit the use of pointers? Not likely! Careful use of pointers

No modification of input parameters All output is clearly separated from the input Output = function_name(input) Subroutine_name (input; output)

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)

Called pattern matching . And pattern matching is an important component of Haskell (more later)

Examples of Polymorphism head head (x:xs) :: [a] -> a = x

tail :: [a] -> [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

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

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

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

Simplification of three first, three infinity = 3 the expression terminates in one step

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

Lazy Evaluation Guarantees termination whenever termination is possible Allows the OS to choose an efficient evaluation order

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

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

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,

Haskell Fundamental Data Types Bool: True or False Char: a , '\n', '\x05e0 , \122 a newline z Number:1 2.718

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

fst(1,2,3) is not defined in the standard environment

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

All elements of a list must be of the same type [[1,2],[1]] is a valid list

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 -}

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 > character

Compiler flags allow for reconfiguration of the literate style

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 > fact 0 = 1 > fact n = n * fact (n-1) And a blank line is required after the code as well

Quick Sort Algorithmqsort [] = [] qsort ( x:xs) = qsort (filter (< x) xs) ++ qsort (filter ( >= x) xs) Inefficient! Calls filter twice for xs Can use (length (x:xs))2memory

More Efficient quicksortqsort [] = [] qsort x:xs = qsort ys ++ [x] ++ qsort zs where (ys, zs) = partition (< x) xs Avoids filtering xs twice Still can use n2 memory! Notice that the < is necessary in the comparison to preserve the original order of identical elements

User Defined Types Enumerated Types data Typename = Type1 | Type2| Type3

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)

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

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

User Defined Types data Bool = True | False Bool is the type constructor True and False are the data constructors

data Color = Red | Green | Blue | Indigo data Point a = Pt a a a on the lhs is a type variable

data Tree a = Branch (Tree a) (Tree a) | Leaf a a is a constituent type on the rhs

Type Synonyms General Definition Unknown (examples only) type String = [Char] type Person = (Name, Address) type Name = String data Address = None | Addr String

Pythagorian Triadsmodule PythagorianTriads where triples :: Int -> [(Int, Int, Int)] triples n = [(x, y, z) | x