Download Software Architecture Research Group

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Lazy Functional Programming
in Haskell
H. Conrad Cunningham, Yi Liu, and Hui Xiong
Software Architecture Research Group
Computer and Information Science
University of Mississippi
Programming 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, …
2-Apr-2004
2
Orderly Expressions and
Disorderly Statements
{ 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
2-Apr-2004
3
Why 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
2-Apr-2004
4
Why 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
2-Apr-2004
5
Haskell 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/hugs
2-Apr-2004
6
Quicksort Algorithm
•
•
•
If sequence is empty, then it is sorted
Take any element as pivot value
Partition rest of sequence into two parts
1. elements < pivot value
2. elements >= pivot value
•
•
Sort each part using Quicksort
Result is sorted part 1, followed by pivot,
followed by sorted part 2
2-Apr-2004
7
Quicksort in C
qsort( a, lo, hi ) int a[ ], hi, lo;
{ int h, l, p, t;
if (lo < hi)
{ l = lo; h = hi; p = a[hi];
do
{ while ((l < h) && (a[l] <= p)) l = l + 1;
while ((h > l) && (a[h] >= p)) h = h – 1 ;
if (l < h) { t = a[l]; a[l] = a[h]; a[h] = t; }
} while (l < h);
t = a[l]; a[l] = a[hi]; a[hi] = t;
qsort( a, lo, l-1 ); qsort( a, l+1, hi );
}
}
2-Apr-2004
8
Quicksort in Haskell
qsort :: [Int] -> [Int]
qsort []
= []
qsort (x:xs) = qsort lt ++ [x] ++ qsort greq
where
lt
= [y | y <- xs, y < x]
greq = [y | y <- xs, y >= x]
2-Apr-2004
9
Types
• Basic types
–
–
–
–
–
Bool
Int
Float
Double
Char
• Structured types
–
–
–
–
lists []
tuples ( , )
user-defined types
functions ->
2-Apr-2004
10
Definitions
• Definitions
name :: type
e.g.:
size :: Int
size = 12 - 3
• Function definitions
name :: t1 -> t2 -> … -> tk -> t
function name
types of
arguments
type of result
e.g.:
exOr :: Bool -> Bool -> Bool
exOr x y = (x || y) && not (x && y)
2-Apr-2004
11
Factorial Function
fact1 :: Int -> Int
fact1 n
-- use guards on two equations
| n == 0
=1
|n>0
= n * fact1 (n-1)
2-Apr-2004
12
Another Factorial Function
fact1 :: Int -> Int
fact1 n
-- use guards on two equations
| n == 0
=1
|n>0
= n * fact1 (n-1)
fact2 :: Int -> Int
fact2 0
= 1 -- use pattern matching
fact2 (n+1) = (n+1) * fact n
fact1 and fact2 represent the same function
2-Apr-2004
13
Yet Another Factorial Function
fact2 :: Int -> Int
fact2 0
=1
fact2 (n+1) = (n+1) * fact n
fact3 :: Int -> Int
fact3 n = product [1..n] -- library functions
fact3 differs slightly from fact1 and fact
Consider fact2 (-1) and fact3 (-1)
2-Apr-2004
14
List Cons and Length
(x:xs) on right side of defining equation means to form new list
with x as head element and xs as tail list – colon is “cons”
(x:xs) 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] -> Int -- polymorphic list argument
len []
=0
-- nil list
len (x:xs) = 1 + len xs -- non-nil list
2-Apr-2004
15
List Append
infixr 5 ++
-- infix operator
-- note polymorphism
(++) :: [a] -> [a] -> [a]
[]
++ xs = xs
-- infix pattern match
(x:xs) ++ ys = x:(xs ++ ys)
2-Apr-2004
16
Abstraction: Higher-Order Functions
squareAll :: [Int] -> [Int]
squareAll []
= []
squareAll (x:xs) = (x * x) : squareAll xs
lengthAll :: [[a]] -> [Int]
lengthAll []
= []
lenghtAll (xs:xss) = (length xs) : lengthAll xss
2-Apr-2004
17
Map
Abstract different functions applied as function argument to a
library function called map
map :: (a -> b) -> [a] -> [b]
map f []
= []
map f (x:xs) = (f x) : map f xs
squareAll xs = map sq xs
where sq x = x * x -- local function def
squareAll’ xs = map (\x -> x * x) xs -- anonymous function
-- or lambda expression
lengthAll xs = map length xs
2-Apr-2004
18
Another Higher-Order Function
getEven :: [Int] -> [Int]
getEven []
= []
getEven (x:xs)
| even x
= x : getEven xs
| otherwise = getEven xs
doublePos :: [Int] -> [Int]
doublePos [] = []
doublePos (x:xs)
|0<x
= (2 * x) : doublePos xs
| otherwise = doublePos xs
2-Apr-2004
19
Filter
filter :: (a -> Bool) -> [a] -> [a]
filter _ []
= []
filter p (x:xs) | p x
= x : xs'
| otherwise = xs'
where xs' = filter p xs
getEven :: [Int] -> [Int]
getEven xs = filter even xs -- use library function
doublePos :: [Int] -> [Int]
doublePos xs = map dbl (filter pos xs)
where dbl x = 2 * x
pos x = (0 < x)
2-Apr-2004
20
Yet Another Higher-Order Function
sumlist :: [Int] -> Int
sumlist []
=0
-- nil list
sumlist (x:xs) = x + sumlist xs -- non-nil
concat' :: [[a]] -> [a]
concat' []
= []
-- nil list of lists
concat' (xs:xss) = xs ++ concat' xss -- non-nil
2-Apr-2004
21
Fold Right
Abstract different binary operators to be applied
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f z []
=z
-- binary op, identity, list
foldr f z (x:xs) = f x (foldr f z xs)
sumlist :: [Int] -> Int
sumlist xs = foldr (+) 0 xs
concat' :: [[a]] -> [a]
concat' xss = foldr (++) [] xss
2-Apr-2004
22
Divide and Conquer Function
divideAndConquer ::
(a -> Bool)
-- trivial
-> (a -> b)
-- simplySolve
-> (a -> [a])
-- decompose
-> (a -> [b] -> b) -- combineSolutions
-> a
-- problem
-> b
divideAndConquer trivial simplySolve decompose
combineSolutions problem
= solve problem
where solve p
| trivial p = simplySolve p
| otherwise = combineSolutions p
map solve (decompose p))
2-Apr-2004
23
Divide and Conquer Function
fib :: Int -> Int
fib n = divideAndConquer trivial simplySolve
decompose combineSolutions n
where trivial 0
= True
trivial 1
= True
trivial (m+2) = False
simplySolve 0 = 0
simplySolve 1 = 1
decompose m = [m-1,m-2]
combineSolutions _ [x,y] = x + y
2-Apr-2004
24
Currying and Partial Evaluation
add :: (Int,Int) -> Int
add (x,y) = x + y
add' :: Int->(Int->Int)
add' x y = x + y
? add(3,4) => 7
? add (3, ) => error
? add’ 3 4 => 7
? add’ 3
add’ takes one argument and
returns a function
Takes advantage of Currying
2-Apr-2004
(add’ 3) :: Int -> Int
(add’ 3) x = 3 + x
((+) 3)
25
Using Partial Evaluation
doublePos :: [Int] -> [Int]
doublePos xs = map ((*) 2) (filter ((<) 0) xs)
• Using operator section notation
doublePos xs = map (*2) (filter (0<) xs)
• Using list comprehension notation
doublePos xs = [ 2*x | x <- xs, 0< x ]
2-Apr-2004
26
Lazy Evaluation
Do not evaluate an expression unless its value is needed
iterate :: (a -> a) -> a -> [a]
iterate f x = x : iterate f (f x)
interate (*2) 1 => [1, 2, 4, 8, 16, …]
powertables :: [[Int]]
powertables = [ iterate (*n) 1 | n <- [2..] ]
powertables => [ [1, 2, 4, 8,…],
[1, 3, 9, 27,…],
[1, 4,16, 64,…],
[1, 5, 25,125,…], … ]
2-Apr-2004
27
Sieve of Eratosthenes Algorithm
1.
2.
3.
4.
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 (p:xs) = [x | x <- xs, x `mod` p /= 0 ]
takewhile (< 10000) primes
2-Apr-2004
28
Hamming’s Problem
Produce the list of integers
• increasing order (hence no duplicate values)
• begins with 1
• if n is in list, then so is 2*n, 3*n, and 5*n
• list contains no other elements
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, …
2-Apr-2004
29
Hamming Program
ham :: [Int]
ham = 1 : merge3 [ 2*n | n <- ham ]
[ 3*n | n <- ham ]
[ 5*n | n <- ham ]
merge3 :: Ord a => [a] -> [a] -> [a] -> [a]
merge3 xs ys zs = merge2 xs (merge2 ys zs)
merge2 xs'@(x:xs)
|x<y
=
|x>y
=
| otherwise =
2-Apr-2004
ys'@(y:ys)
x : merge2 xs ys'
y : merge2 xs' ys
x : merge2 xs ys
30
User-Defined Data Types
data BinTree a
= Empty | Node (BinTree a) a (BinTree a)
height :: BinTree -> Int
height Empty
=0
height (Node l v r) = max (height l) (height r) + 1
flatten :: BinTree a -> [a]
-- in-order traversal
flatten Empty
= []
flatten (Node l v r) = flatten l ++ [v] ++ flatten r
2-Apr-2004
31
Other 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
2-Apr-2004
32
Other 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)
2-Apr-2004
33
Haskell-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
2-Apr-2004
34
Other 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.
2-Apr-2004
35
Acknowledgements
• 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.
2-Apr-2004
36
Related documents