Title: Lazy Functional Programming in Haskell
1Lazy Functional Programming in Haskell
- H. Conrad Cunningham, Yi Liu, and Hui Xiong
- Software Architecture Research Group
- Computer and Information Science
- University of Mississippi
2Programming Language Paradigms
- Imperative languages
- have implicit states
- use commands to modify state
- express how something is computed
- include C, Pascal, Ada,
- Declarative languages
- have no implicit states
- use expressions that are evaluated
- express what is to be computed
- have different underlying models
- functions Lisp (Pure), ML, Haskell,
spreadsheets? SQL? - relations (logic) Prolog (Pure) , Parlog,
3Orderly Expressions andDisorderly Statements
x 1 y 2 z 3 x 1 y 2 z 3
x 3 x 2 y z
y 5 x y 2 z
Values of x and y depend upon order of execution
of statements x represents different values in
different contexts
4Why Use Functional Programming?
- Referential transparency
- symbol always represents the same value
- easy mathematical manipulation, parallel
execution, etc. - Expressive and concise notation
- Higher-order functions
- take/return functions
- powerful abstraction mechanisms
- Lazy evaluation
- defer evaluation until result needed
- new algorithmic approaches
5Why Teach/Learn FP and Haskell?
- Introduces new problem solving techniques
- Improves ability to build and use higher-level
procedural and data abstractions - Helps instill a desire for elegance in design and
implementation - Increases comfort and skill in use of recursive
programs and data structures - Develops understanding of programming languages
features such as type systems - Introduces programs as mathematical objects in a
natural way
6Haskell and Hugs
- Haskell
- Standard functional language for research
- Work began in late 1980s
- Web site http//www.haskell.org
- Hugs
- Interactive interpreter for Haskell 98
- Download from http//www.haskell.org/hu
gs
7Quicksort Algorithm
- If sequence is empty, then it is sorted
- Take any element as pivot value
- Partition rest of sequence into two parts
- elements lt pivot value
- elements gt pivot value
- Sort each part using Quicksort
- Result is sorted part 1, followed by pivot,
followed by sorted part 2
8Quicksort in C
- qsort( a, lo, hi ) int a , hi, lo
- int h, l, p, t
- if (lo lt hi)
- l lo h hi p ahi
- do
- while ((l lt h) (al lt p)) l
l 1 - while ((h gt l) (ah gt p)) h
h 1 - if (l lt h) t al al
ah ah t - while (l lt h)
- t al al ahi ahi t
- qsort( a, lo, l-1 ) qsort( a, l1,
hi ) -
-
9Quicksort in Haskell
- qsort Int -gt Int
- qsort
- qsort (xxs) qsort lt x qsort greq
- where
- lt y y lt-
xs, y lt x - greq y y lt-
xs, y gt x
10Types
- Basic types
- Bool
- Int
- Float
- Double
- Char
- Structured types
- lists
- tuples ( , )
- user-defined types
- functions -gt
11Definitions
- Definitions
- name type
- e.g.
- size Int
- size 12 - 3
- Function definitions
- name t1 -gt t2 -gt -gt tk -gt t
- function name types of
type of result -
arguments - e.g.
- exOr Bool -gt Bool -gt Bool
- exOr x y (x y) not (x y)
12Factorial Function
- fact1 Int -gt Int
- fact1 n -- use guards on two
equations - n 0 1
- n gt 0 n fact1 (n-1)
13Another Factorial Function
- fact1 Int -gt Int
- fact1 n -- use guards on two
equations - n 0 1
- n gt 0 n fact1 (n-1)
- fact2 Int -gt Int
- fact2 0 1 -- use pattern matching
- fact2 (n1) (n1) fact n
- fact1 and fact2 represent the same function
14Yet Another Factorial Function
- fact2 Int -gt Int
- fact2 0 1
- fact2 (n1) (n1) fact n
- fact3 Int -gt Int
- fact3 n product 1..n -- library functions
- fact3 differs slightly from fact1 and fact
- Consider fact2 (-1) and fact3 (-1)
15List Cons and Length
- (xxs) on right side of defining equation means
to form new list with x as head element and xs as
tail list colon is cons - (xxs) on left side of defining equation means to
match a list with at least one element, x gets
head element, xs gets tail list - x1, x2, x3 gives explicit list of elements,
is nil list - len a -gt Int -- polymorphic list argument
- len 0 -- nil list
- len (xxs) 1 len xs -- non-nil list
16List Append
- infixr 5 -- infix operator
- -- note polymorphism
- () a -gt a -gt a
- xs xs -- infix pattern
match - (xxs) ys x(xs ys)
17Abstraction Higher-Order Functions
- squareAll Int -gt Int
- squareAll
- squareAll (xxs) (x x) squareAll xs
- lengthAll a -gt Int
- lengthAll
- lenghtAll (xsxss) (length xs) lengthAll xss
18Map
- Abstract different functions applied as function
argument to a library function called map - map (a -gt b) -gt a -gt b
- map f
- map f (xxs) (f x) map f xs
- squareAll xs map sq xs
- where sq x x x --
local function def - squareAll xs map (\x -gt x x) xs --
anonymous function -
-- or lambda expression - lengthAll xs map length xs
19Another Higher-Order Function
- getEven Int -gt Int
- getEven
- getEven (xxs)
- even x x getEven xs
- otherwise getEven xs
- doublePos Int -gt Int
- doublePos
- doublePos (xxs)
- 0 lt x (2 x) doublePos xs
- otherwise doublePos xs
20Filter
- filter (a -gt Bool) -gt a -gt a
- filter _
- filter p (xxs) p x x xs'
- otherwise xs'
- where xs' filter p
xs - getEven Int -gt Int
- getEven xs filter even xs -- use library
function - doublePos Int -gt Int
- doublePos xs map dbl (filter pos xs)
- where dbl x 2 x
- pos x (0
lt x)
21Yet Another Higher-Order Function
- sumlist Int -gt Int
- sumlist 0 -- nil
list - sumlist (xxs) x sumlist xs -- non-nil
- concat' a -gt a
- concat' -- nil
list of lists - concat' (xsxss) xs concat' xss -- non-nil
22Fold Right
- Abstract different binary operators to be applied
- foldr (a -gt b -gt b) -gt b -gt a -gt b
- foldr f z z -- binary op,
identity, list - foldr f z (xxs) f x (foldr f z xs)
- sumlist Int -gt Int
- sumlist xs foldr () 0 xs
- concat' a -gt a
- concat' xss foldr () xss
23Divide and Conquer Function
- divideAndConquer
- (a -gt Bool) -- trivial
- -gt (a -gt b) -- simplySolve
- -gt (a -gt a) -- decompose
- -gt (a -gt b -gt b) -- combineSolutions
- -gt a -- problem
- -gt b
- divideAndConquer trivial simplySolve decompose
- combineSolutions
problem - solve problem
- where solve p
- trivial p simplySolve
p - otherwise
combineSolutions p - map
solve (decompose p))
24Divide and Conquer Function
- fib Int -gt Int
- fib n divideAndConquer trivial simplySolve
- decompose combineSolutions n
- where trivial 0 True
- trivial 1 True
- trivial (m2) False
- simplySolve 0 0
- simplySolve 1 1
- decompose m m-1,m-2
- combineSolutions _ x,y x
y
25Currying and Partial Evaluation
- add (Int,Int) -gt Int
- add (x,y) x y
- ? add(3,4) gt 7
- ? add (3, ) gt error
- add takes one argument and returns a function
- Takes advantage of Currying
- add' Int-gt(Int-gtInt)
- add' x y x y
- ? add 3 4 gt 7
- ? add 3
- (add 3) Int -gt Int
- (add 3) x 3 x
- (() 3)
26Using Partial Evaluation
- doublePos Int -gt Int
- doublePos xs map (() 2) (filter ((lt) 0) xs)
- Using operator section notation
- doublePos xs map (2) (filter (0lt) xs)
- Using list comprehension notation
- doublePos xs 2x x lt- xs, 0lt x
27Lazy Evaluation
- Do not evaluate an expression unless its value is
needed - iterate (a -gt a) -gt a -gt a
- iterate f x x iterate f (f x)
- interate (2) 1 gt 1, 2, 4, 8, 16,
- powertables Int
- powertables iterate (n) 1 n lt- 2..
- powertables gt 1, 2, 4, 8,,
- 1, 3, 9, 27,,
- 1, 4,16, 64,,
- 1, 5, 25,125,,
28Sieve of Eratosthenes Algorithm
- Generate list 2, 3, 4,
- Mark first element p of list as prime
- Delete all multiples of p from list
- Return to step 2
- primes Int
- primes map head (iterate sieve 2..)
- sieve (pxs) x x lt- xs, x mod p / 0
- takewhile (lt 10000) primes
29Hammings Problem
- Produce the list of integers
- increasing order (hence no duplicate values)
- begins with 1
- if n is in list, then so is 2n, 3n, and 5n
- list contains no other elements
- 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20,
30Hamming Program
- ham Int
- ham 1 merge3 2n n lt- ham
- 3n n lt- ham
- 5n n lt- ham
- merge3 Ord a gt a -gt a -gt a -gt a
- merge3 xs ys zs merge2 xs (merge2 ys zs)
- merge2 xs'_at_(xxs) ys'_at_(yys)
- x lt y x merge2 xs ys'
- x gt y y merge2 xs' ys
- otherwise x merge2 xs ys
31User-Defined Data Types
- data BinTree a
- Empty Node (BinTree a) a (BinTree a)
- height BinTree -gt Int
- height Empty 0
- height (Node l v r) max (height l) (height r)
1 - flatten BinTree a -gt a -- in-order
traversal - flatten Empty
- flatten (Node l v r) flatten l v
flatten r
32Other Important Haskell Features
- Type inferencing
- Type classes and overloading
- Rich set of built-in types
- Extensive libraries
- Modules
- Monads for purely functional I/O and other actions
33Other Important FP Topics
- Problem solving and program design techniques
- Abstract data types
- Proofs about functional program properties
- Program synthesis
- Reduction models
- Parallel execution (dataflow interpretation)
34Haskell-based Textbooks
- Simon Thompson. Haskell The Craft of Functional
Programming, Addison Wesley, 1999. - Richard Bird. Introduction to Functional
Programming Using Haskell, second edition,
Prentice Hall Europe, 1998. - Paul Hudak. The Haskell School of Expression,
Cambridge University Press, 2000. - H. C. Cunningham. Notes on Functional Programming
with Gofer, Technical Report UMCIS-1995-01,
University of Mississippi, Department of Computer
and Information Science, Revised January 1997.
http//www.cs.olemiss.edu/hcc/reports/gofer_notes
.pdf
35Other FP Textbooks Of Interest
- Fethi Rabhi and Guy Lapalme. Algorithms A
Functional Approach, Addison Wesley, 1999. - Chris Okasaki. Purely Functional Data Structures,
Cambridge University Press, 1998.
36Acknowledgements
- Individuals who helped me get started teaching
lazy functional programming in the early 1990s. - Mark Jones and others who implemented the Hugs
interpreter. - More than 200 students who have been in my 10
classes on functional programming in the past 14
years. - Acxiom Corporation for funding some of my recent
work on software architecture.