Post on 07-Jan-2016

36 views

Category:

## Documents

Tags:

• #### int intdouble n

Embed Size (px)

DESCRIPTION

Functional Programming in Haskell. Motivation through Concrete Examples Adapted from Lectures by Simon Thompson. Functional Programming. Given the functions above invertColour flipH sideBySide superimpose flipV and the horse picture, - PowerPoint PPT Presentation

TRANSCRIPT

Motivation through Concrete Examples

• CS7120 (Prasad)L5-Haskell*Functional Programming Given the functionsabove invertColour flipH sideBySide superimpose flipVand the horse picture, how do you get

(expression and evaluation)

blackHorse :: PictureblackHorse = invertColour horse

rotate :: Picture -> Picturerotate pic = flipH (flipV pic)

No need to allocate/deallocate storage: garbage collection.

Values don't change over program execution: contrast x=x+1 etc. of Java, C, instead we describe relations between values by means of (fixed) functions.

• CS7120 (Prasad)L5-Haskell*Declarative proofs possiblePrograms describe themselves: square n = n*n double n = 2*n

'The square of n is n*n, for every integer n.'Programs are equations.So we can write proofs using the definitions.

square (double n) = square (2*n) = (2*n)*(2*n) = 2*2*n*n= double (double (square n))

(4-3)+(2-1) (4-3)+(2-1) (4-3)+(2-1) (4-3)+1 1+(2-1) 1+1 1+1 1+1 2 2 2 and can choose to evaluate only what is needed, when it is needed: lazy evaluation (more later).

Can also evaluate in parallel efficiently?

• CS7120 (Prasad)L5-Haskell*HistoryFirst 'functional' language, LISP, defined c. 1960 popular in AI in 70s/80s. Now represented best by Scheme. Weakly typed; allows side-effects and eval.

Next generation: ML (1980), Miranda (1985) and Haskell (1990). Strongly-typed; ML allows references and thus side-effects. Miranda and Haskell: pure and lazy. FP (1982): heroic experiment by Backus (FORTRAN, ALGOL).

Various implementations: Hugs (interpreter for Windows, Mac, Unix) and GHC, NHC, HBC (compilers).

• Basics: guards and base typesHow many of three integers are equal ?

howManyEqual :: Int -> Int -> Int -> Int

howManyEqual n m k | n==m && m==k = 3 | n==m || m==k || k==n = 2 | otherwise = 1CS7120 (Prasad)L5-Haskell*

-- FirstScript.hs-- 5 October 2000

-- Double an integer.

double :: Int -> Intdouble n = 2*n

Everything is program, except comments beginning --. In a literate script there are comments and definitions:

FirstLit.lhs5 October 2000

Double an integer.

> double :: Int -> Int> double n = 2*n

Everything is comment, except program beginning > .

With the nth cut, you get n more pieces:

cuts :: Int -> Intcuts n | n==0 = 1 | n>0 = cuts (n-1) + n | otherwise = 0

Using a powerful library of functions over lists. Pattern matching Recursion Generic functions Higher-order functions

exprEvaluate expr:type exprGive the type of expr:l BlahLoad the file Blah.hs:rReload the last file:?Help: list commands:eEdit the current file:qQuit

• CS7120 (Prasad)L5-Haskell*Functions over picturesA function to flip a picture in a vertical mirror:flipV

• CS7120 (Prasad)L5-Haskell*Functions over picturesA function to invert the colours in a picture:

• CS7120 (Prasad)L5-Haskell*Functions over picturesA function to put one picture above another:above

• CS7120 (Prasad)L5-Haskell*Functions over picturesA function to put two pictures side by side:sideBySide

A Picture is a list of Strings.A String is a list of Char (acters)........##........##..#.....##.....#...#.......#...#...#...#...#...###.#..#....#..##...#...#........#...#........#..#.........#.#..........##....

• CS7120 (Prasad)L5-Haskell*How are they implemented?flipHReverse the list of strings.flipVReverse each string.rotateflipH then flipV (or v.versa).aboveJoin the two lists of strings.sideBySideJoin corresponding lines.invertColourChange each Char and each line.superimposeJoin each Char join each line.

• CS7120 (Prasad)L5-Haskell*How are they implemented?flipHreverseflipVmap reverserotateflipV . flipH above++sideBySidezipWith (++)invertColourmap (map invertChar)superimposezipWith (zipWith combine)

For each type t there is a type [t], 'list of t'.

reverse [] = []reverse (x:xs) = reverse xs ++ [x]

reverse :: [a] -> [a]

a is a type variable: reverse works over any list type, returning a list of the same type.

flipV [] = []flipV (x:xs) = reverse x : flipV xs

Run along the list, applying reverse to each element

Run along the list, applying to every element.

General pattern of computation.

• CS7120 (Prasad)L5-Haskell*Implementing the mapping patternmap f [] = []map f (x:xs) = f x : map f xs

map :: (a -> b) -> [a] -> [b]

Examples over pictures:

flipV pic = map reverse picinvertColour pic = map invertLine picinvertLine line = map invertChar line

• CS7120 (Prasad)L5-Haskell*Functions as dataHaskell allows you to pass functions as arguments and return functions as results, put them into lists, etc. In contrast, in Pascal and C, you can only pass named functions, not functions you build dynamically.

map isEven = ??map isEven :: [Int] -> [Bool]

It is a partial application, which gives a function:give it a [Int] and it will give you back a [Bool]

invertColour = map (map invertChar)

• CS7120 (Prasad)L5-Haskell*Another pattern: zipping togethersideBySide [l1,l2,l3] [r1,r2,r3] = [ l1++r1, l2++r2, l3++r3 ]zipWith :: (a->b->c) -> [a] -> [b] -> [c]zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys

zipWith f xs ys = []

Superimposing two pictures: need to combine individual elements:

combine :: Char -> Char -> Charcombine top btm = if (top=='.' && btm=='.') then '.' else '#'

superimpose = zipWith (zipWith combine)

is a sequence of symbols, but underlying it is a structure ...-423+

a literal, such as 234 or a composite expression:

the sum of two expressions (e1+e2)

the difference of two expressions (e1-e2)

the product of two expressions (e1*e2)

• CS7120 (Prasad)L5-Haskell*How to represent these structures?data Expr = Lit Int | Sum Expr Expr | Minus Expr Expr | Times Expr Expr

Elements of this algebraic data type include

Lit 3434Sum (Lit 45) (Lit 3)(45+3)Minus (Sum (Lit 2) (Lit 3)) (Lit 4)((2+3)-4)

• CS7120 (Prasad)L5-Haskell*Counting operatorsdata Expr = Lit Int | Sum Expr Expr | Minus ...

How many operators in an expression?

Definition using pattern matching

cOps (Lit n) = 0cOps (Sum e1 e2) = cOps e1 + cOps e2 + 1cOps (Minus e1 e2) = cOps e1 + cOps e2 + 1cOps (Times e1 e2) = cOps e1 + cOps e2 + 1

• CS7120 (Prasad)L5-Haskell*Evaluating expressionsdata Expr = Lit Int | Sum Expr Expr | Minus ...

Literals are themselves

eval (Lit n) = n

in other cases, evaluate the two arguments and then combine the results

eval (Sum e1 e2) = eval e1 + eval e2eval (Minus e1 e2) = eval e1 - eval e2eval (Times e1 e2) = eval e1 * eval e2