Title: Haskell
1Haskell
- Data Types/ADT/Modules
- Type/Class Hierarchy
- Lazy Functional Language
2Modelling Alternatives
New data types are useful to model values with
several alternatives. Example Recording phone
calls. type History (Event, Time) type Time
Int data Event Call String Hangup
The number called.
E.g. Call 031-7721001, Hangup, etc.
3Extracting a List of Calls
We can pattern match on values with components as
usual. Example Extract a list of completed calls
from a list of events. calls History -gt
(String, Time, Time) calls ((Call number,
start) (Hangup, end) history)
(number, start, end) calls history calls (Call
number, start) -- a
call is going on now calls
4Defining Recursive Data Types
data Tree a Node a (Tree a) (Tree a)
Leaf deriving Show
Types of the components.
Enables us to define polymorphic functions which
work on a tree with any type of labels.
5Tree Insertion
Pattern matching works as for lists.
Additional requirement
insertTree Ord a gt a -gt Tree a -gt Tree
a insertTree x Leaf Node x Leaf Leaf insertTree
x (Node y l r) x lt y Node y (insertTree x
l) r x gt y Node y l (insertTree x r)
xy Node y l r
6Modelling Expressions
Lets design a datatype to model arithmetic
expressions -- not their values, but their
structure.
- An expression can be
- a number n
- a variable x
- an addition ab
- a multiplication ab
data Expr Num Int Var String
Add Expr Expr Mul Expr Expr
A recursive data type !!
7Symbolic Differentiation
Differentiating an expression produces a new
expression. derive Expr -gt String -gt
Expr derive (Num n) x Num 0 derive (Var y) x
xy Num 1 x/y Num 0 derive (Add
a b) x Add (derive a x) (derive b x) derive
(Mul a b) x Add (Mul a (derive b x)) (Mul
b (derive a x))
Variable to differentiate w.r.t.
8Example
d (2x) 2 dx
derive (Mul (Num 2) (Var x)) x Add (Mul (Num
2) (derive (Var x) x)) (Mul (Var
x) (derive (Num 2) x)) Add (Mul (Num 2) (Num
1)) (Mul (Var x) (Num 0))
21 x0
9Formatting Expressions
Expressions will be more readable if we convert
them to strings. formatExpr (Mul (Num 1)
(Add (Num 2) (Num 3))) 123
formatExpr Expr -gt String formatExpr (Num
n) show n formatExpr (Var x) x formatExpr
(Add a b) formatExpr a formatExpr
b formatExpr (Mul a b) formatExpr a
formatExpr b
10Quiz
NO!
Which brackets are necessary? 1(23) 1(23)
1(23) What kind of expression may need
to be bracketed? When does it need to be
bracketed?
NO!
YES!
Additions
Inside multiplications.
11Idea
Give formatExpr an extra parameter, to tell it
what context its argument appears in. data
Context Multiply AnyOther formatExpr (Add a
b) Multiply ( formatExpr (Add a
b) AnyOther ) formatExpr (Mul a b) _
formatExpr a Multiply
formatExpr b Multiply
12 13module construct in Haskell
- Enables grouping a collection of related
definitions - Enables controlling visibility of names
- export public names to other modules
- import names from other modules
- disambiguation using fully qualified names
- Enables defining Abstract Data Types
14- module MTree ( Tree(Leaf,Branch), fringe )
- wheredata Tree a Leaf a Branch (Tree a) (Tre
e a) fringe Tree a -gt afringe (Leaf x)
xfringe (Branch left right) - fringe left fringe right
- This definition exports all the names defined in
the module including Tree-constructors.
15- module Main (main) where
- import
- MTree ( Tree(Leaf,Branch), fringe )
- main
- do print (fringe
- (Branch (Leaf 1) (Leaf 2))
- )
- Main explicitly imports all the names exported by
the module MTree.
16- module Fringe(fringe) where
- import Tree(Tree(..))
- fringe Tree a -gt a
- -- A different definition of fringe
- fringe (Leaf x) x
- fringe (Branch x y) fringe x
- module QMain where
- import Tree ( Tree(Leaf,Branch), fringe )
- import qualified Fringe ( fringe )
- qmain
- do print (fringe (Branch (Leaf 1) (Leaf 2)))
print(Fringe.fringe(Branch (Leaf 1) (Leaf 2)
))
17Abstract Data Types
- module TreeADT (Tree, leaf, branch, cell,
left, right, isLeaf) where - data Tree a
- Leaf a Branch (Tree a) (Tree a)
- leaf Leaf
- branch Branch
- cell (Leaf a) a
- left (Branch l r) l
- right (Branch l r) r
- isLeaf (Leaf _) True
- isLeaf _ False
18Other features
- Selective hiding
- import Prelude hiding length
- Eliminating functions inherited on the basis of
the representation. - module Queue( operation names...) where
- newtype Queue a MkQ (a,a)
- operation implementation
- Use of MkQ-constructor prevents equality testing,
printing, etc of queue values.
19- Treatment of Overloading through Type/Class
Hierarchy
20Kinds of functions
- Monomorphic (defined over one type)
- capitalize Char -gt Char
- Polymorphic (defined similarly over all types)
- length a -gt Int
- Overloaded (defined differently and over many
types) - () Char -gt Char -gt Bool
- () (Int,Bool -gt
- (Int,Bool -gt Bool
21Overloading problem in SML
- fun add x y x y
- SML-90 treats this definition as ambiguous
- int -gt int -gt int
- real -gt real -gt real
- SML-97 defaults it to
- int -gt int -gt int
- Ideally, add defined whenever is defined on a
type. - add (hasPlus a) gt a -gt a -gt a
22Parametric vs ad hoc polymorphism
- Polymorphic functions use the same definition at
each type. - Overloaded functions may have a different
definition at each type.
Class name.
class Eq a where () a -gt a -gt Bool
(/) a -gt a -gt Bool x/y not (xy)
Read a is a type in class Eq, if it has the
following methods.
Class methods and types.
Default definition.
23 Class Hierarchy and Instance Declarations
class Eq a gt Ord a where (lt),(lt),(gt),(gt)
a -gt a -gt Bool max, min a
-gt a -gt a
Read Type a in class Eq is also in class Ord,
if it provides the following methods
instance Eq Integer where xy primitive
instance Eq a gt Eq a where
True xxs yys x y
xs ys
If a is in class Eq, then a is in class Eq,
with the method definition given.
24Types of Overloaded Functions
a may be any type in class Ord.
insert Ord a gt a -gt a -gt a insert x
insert x (yxs) xlty xyxs
xgty yinsert x xs
f (Eq a) gt a -gt a -gt Int f x y if xy
then 1 else 2
Because insert uses a method from class Ord.
25Show and Read
class Show a where show a -gt String
class Read a where read String -gt a
read . show id (usually)
These are definitions are simplifications there
are more methods in reality.
26Derived Instances
data Tree a Node a (Tree a) (Tree a)
Leaf deriving (Eq, Show)
Constructs a default instance of class
Show. Works for standard classes.
Maingt show (Node 1 Leaf (Node 2 Leaf Leaf)) "Node
1 Leaf (Node 2 Leaf Leaf)"
27Multi-Parameter Classes
Define relations between classes.
class Collection c a where empty c add
a -gt c -gt c member a -gt c -gt Bool
c is a collection with elements of type a.
instance Eq a gt Collection a a where
empty add () member elem
instance Ord a gt Collection (Tree a) a where
empty Leaf add insertTree member
elemTree
28Multiple Inheritance
class (Ord a, Show a) gt a where SortAndPrint
function
Advanced Features Module, ADT,
29Functional Dependencies
A functional dependency
class Collection c a c -gt a where empty
c add a -gt c -gt c member a -gt c -gt
Bool
- Declares that c determines a there can be only
one instance for each type c. - Helps the type-checker resolve ambiguities
(tremendously).
add x (add y empty) -- x and y must be the same
type.
30- class MyFunctor f where
- tmap (a -gt b) -gt f a -gt f b
- data Tree a Branch (Tree a) (Tree a)
- Leaf a
- deriving Show
- instance MyFunctor Tree where
- tmap f (Leaf x) Leaf (f x)
- tmap f (Branch t1 t2)
- Branch (tmap f t1) (tmap f t2)
- tmap (10) (Branch (Leaf 1) (Leaf 2))
31Higher-Order Functions
- Functions are values in Haskell.
- Program skeletons take functions as parameters.
takeWhile (a -gt Bool) -gt a -gt a takeWhile
p takeWhile p (xxs) p x
xtakeWhile p xs otherwise
Takes a prefix of a list, satisfying a predicate.
32More Ways to Denote Functions
- below a b b lt a
- takeWhile (below 10) 1,5,9,15,20
- takeWhile (\b -gt b lt 10) 1,5,9,15,20
- takeWhile (lt10) 1,5,9,15,20
Lambda expression. Function definition in place.
Partial operator application -- argument replaces
missing operand.
33Lazy Evaluation
fib 1 1 ab (a,b)lt- zip fib (tail
fib)
- Expressions are evaluated only when their value
is really needed! - Function arguments, data structure components,
are held unevaluated until their value is used.
nats 0 map (1) nats
34Non-strict / Lazy Functional Language
- Parameter passing mechanism
- Call by name
- Call by need
- ( but not Call by value )
- Advantages
- Does not evaluate arguments not required to
determine the final value of the function. - Most likely to terminate evaluation order.
- fun const x 0 const (1/0) 0
35- Practical Benefits
- Frees programmer from worrying about control
issues - Best order for evaluation
- To compute or not to compute a subexpression
- Facilitates programming with potentially infinite
value or partial value. - Costs
- Overheads of building thunks to represent delayed
argument.