Functional Programming in Haskell

  • View

  • Download

Embed Size (px)


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

Text of Functional Programming in Haskell

  • Functional Programming in Haskell

    Motivation through Concrete Examples

    Adapted from Lectures bySimon Thompson


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

    (expression and evaluation)


  • CS7120 (Prasad)L5-Haskell*Definitions in Haskellname :: Typename = expression

    blackHorse :: PictureblackHorse = invertColour horse

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


  • CS7120 (Prasad)L5-Haskell*Higher-levelEvaluation is about expressions and values, not storage locations.

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


  • CS7120 (Prasad)L5-Haskell*Evaluation freedomEvaluation can occur in any order ...

    (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).


  • CS7120 (Prasad)L5-Haskell*Haskell and HugsNamed after Haskell Brooks Curry: mathematician and logician; inventor of the -calculus.

    Haskell 98 is the recent 'standard' version of Haskell.

    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*


  • CS7120 (Prasad)L5-Haskell*Regular and literate scriptsIn a regular script there are definitions and comments:

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


  • CS7120 (Prasad)L5-Haskell*How many pieces with n cuts?


  • CS7120 (Prasad)L5-Haskell*How many pieces with n cuts?No cuts: 1 piece.

    With the nth cut, you get n more pieces:

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


  • CS7120 (Prasad)L5-Haskell*The Pictures case study.

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


  • CS7120 (Prasad)L5-Haskell*Using Hugs

    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 superimpose two pictures:superimpose


  • 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


  • CS7120 (Prasad)L5-Haskell*A nave implementationtype Picture = [String]type String = [Char]

    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)


  • CS7120 (Prasad)L5-Haskell*Lists and typesHaskell is strongly typed: detect all type errors before evaluation.

    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.


  • CS7120 (Prasad)L5-Haskell*Flipping in a vertical mirrorflipV :: Picture -> Picture

    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]


  • CS7120 (Prasad)L5-Haskell*Partial application in PicturesflipV = map reverse

    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 = []


  • CS7120 (Prasad)L5-Haskell*In the case study sideBySide = zipWith (++)

    Superimposing two pictures: need to combine individual elements:

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

    superimpose = zipWith (zipWith combine)


  • CS7120 (Prasad)L5-Haskell*Parsing "((2+3)-4)"

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


  • CS7120 (Prasad)L5-Haskell*Arithmetical expressionsAn expression is either

    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


  • CS7120 (Prasad)L5-Haskell*List comprehensionsExample list x = [4,3,2,5][ n+2 | n
  • CS7120 (Prasad)L5-Haskell* List comprehensionsExample lists x = [4,3,2] y = [12,17][ n+m | n
  • CS7120 (Prasad)L5-Haskell*Quicksortqsort [] = []qsort (x:xs) = qsort elts_lt_x ++ [x] ++ qsort elts_greq_x