CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional...
-
Upload
neal-walker -
Category
Documents
-
view
227 -
download
0
Transcript of CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional...
CS7120(Prasad) L51-Haskell 1
Haskell
Data Types/ADT/Modules
Type/Class Hierarchy
Lazy Functional Language
CS7120(Prasad) L51-Haskell 2
Modelling 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 numbercalled.
E.g. Call ”031-7721001”,Hangup, etc.
CS7120(Prasad) L51-Haskell 3
Extracting 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 -> [(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 [] = []
CS7120(Prasad) L51-Haskell 4
Defining Recursive Data Types
data Tree a = Node a (Tree a) (Tree a) | Leaf deriving Show
Enables us to define polymorphic functions which work on a tree with any type of labels.
Types of thecomponents.
CS7120(Prasad) L51-Haskell 5
Tree Insertion
insertTree :: Ord a => a -> Tree a -> Tree ainsertTree x Leaf = Node x Leaf LeafinsertTree x (Node y l r) | x < y = Node y (insertTree x l) r | x > y = Node y l (insertTree x r) | x==y = Node y l r
Patternmatchingworks asfor lists. Additional
requirement
CS7120(Prasad) L51-Haskell 6
Modelling ExpressionsLet’s 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 a+b
•a multiplication a*b
data Expr =
Num Int
|Var String
| Add Expr Expr
| Mul Expr ExprA recursive data type !!
CS7120(Prasad) L51-Haskell 7
Symbolic Differentiation
Differentiating an expression produces a new expression.
derive :: Expr -> String -> Expr
derive (Num n) x = Num 0
derive (Var y) x | x==y = 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 todifferentiate w.r.t.
CS7120(Prasad) L51-Haskell 8
Exampled (2*x) = 2dx
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))
2*1 + x*0
CS7120(Prasad) L51-Haskell 9
Formatting ExpressionsExpressions will be more readable if we convert them to strings.
formatExpr (Mul (Num 1) (Add (Num 2) (Num 3)))
”1*2+3”
formatExpr :: Expr -> 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
CS7120(Prasad) L51-Haskell 10
Quiz
Which brackets are necessary? 1+(2+3)
1+(2*3)
1*(2+3)
What kind of expression may need to be bracketed?
When does it need to be bracketed?
NO!
YES!
NO!
Additions
Inside multiplications.
CS7120(Prasad) L51-Haskell 11
IdeaGive 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
CS7120(Prasad) L51-Haskell 12
ADT and Modules
CS7120(Prasad) L51-Haskell 13
module 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
CS7120(Prasad) L51-Haskell 14
module MTree ( Tree(Leaf,Branch), fringe )
where
data Tree a = Leaf a | Branch (Tree a) (Tree a)
fringe :: Tree a -> [a]fringe (Leaf x) = [x]fringe (Branch left right) =
fringe left ++ fringe right
• This definition exports all the names defined in the module including Tree-constructors.
CS7120(Prasad) L51-Haskell 15
module Main (main) whereimport 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.
CS7120(Prasad) L51-Haskell 16
module Fringe(fringe) where
import Tree(Tree(..))
fringe :: Tree a -> [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)))
CS7120(Prasad) L51-Haskell 17
Abstract Data Typesmodule TreeADT (Tree, leaf, branch, cell, left, right, isLeaf) where
data Tree a = Leaf a | Branch (Tree a) (Tree a)
leaf = Leafbranch = Branchcell (Leaf a) = aleft (Branch l r) = lright (Branch l r) = risLeaf (Leaf _) = TrueisLeaf _ = False
CS7120(Prasad) L51-Haskell 18
Other features
• Selective hidingimport 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.
CS7120(Prasad) L51-Haskell 19
Treatment of Overloading through Type/Class Hierarchy
CS7120(Prasad) L51-Haskell 20
Kinds of functions
• Monomorphic (defined over one type)
capitalize : Char -> Char
• Polymorphic (defined similarly over all types)
length : [a] -> Int
• Overloaded (defined differently and over many types)
(==) : Char -> Char -> Bool
(==) : [(Int,Bool]] ->
[(Int,Bool]] -> Bool
CS7120(Prasad) L51-Haskell 21
Overloading problem in SML
fun add x y = x + y• SML-90 treats this definition as ambiguous:
int -> int -> int
real -> real -> real• SML-97 defaults it to:
int -> int -> int
• Ideally, add defined whenever + is defined on a type.
add :: (hasPlus a) => a -> a -> a
CS7120(Prasad) L51-Haskell 22
Parametric vs ad hoc polymorphism•Polymorphic functions use the same definition at each type.
•Overloaded functions may have a different definition at each type.
class Eq a where (==) :: a -> a -> Bool (/=) :: a -> a -> Bool x/=y = not (x==y)
Class name.
Classmethods
and types.
Default definition.
Read:
“a is a type in class Eq, if it has the following methods”.
CS7120(Prasad) L51-Haskell 23
Class Hierarchy and Instance Declarations
class Eq a => Ord a where (<),(<=),(>=),(>) :: a -> a -> Bool max, min :: a -> a -> a
Read:
“Type a in class Eq is also in class Ord, if it provides the following methods…”
instance Eq Integer where x==y = …primitive…
instance Eq a => Eq [a] where [] == [] = True x:xs == y:ys =
x == y && xs == ys
If a is in class Eq, then [a] is in class Eq, with the method definition given.
CS7120(Prasad) L51-Haskell 24
Types of Overloaded Functions
insert :: Ord a => a -> [a] -> [a]insert x [] = []insert x (y:xs) | x<=y = x:y:xs
| x>y = y:insert x xs
a may be any typein class Ord.
Because insertuses a method
from class Ord.
f :: (Eq a) => a -> [a] -> Intf x y = if x==y then 1 else 2
CS7120(Prasad) L51-Haskell 25
Show and Read
class Show a where show :: a -> String
class Read a where read :: String -> a
These definitions are simplifications: there are more methods in reality.
read . show = id (usually)
CS7120(Prasad) L51-Haskell 26
Derived Instances
data Tree a = Node a (Tree a) (Tree a) | Leaf deriving (Eq, Show)
Constructs a “defaultinstance” of class Show.
Works for standard classes.
Main> show (Node 1 Leaf (Node 2 Leaf Leaf))"Node 1 Leaf (Node 2 Leaf Leaf)"
CS7120(Prasad) L51-Haskell 27
Multi-Parameter ClassesDefine relations between classes.
class Collection c a where empty :: c add :: a -> c -> c member :: a -> c -> Bool
c is a collection with elements of type a.
instance Eq a => Collection [a] a where empty = [] add = (:) member = elem
instance Ord a => Collection (Tree a) a where empty = Leaf add = insertTree member = elemTree
CS7120(Prasad) L51-Haskell 28
Multiple Inheritance
class (Ord a, Show a) => a where…
SortAndPrint function…
Advanced Features:Module, …ADT, …
CS7120(Prasad) L51-Haskell 29
Functional Dependencies
class Collection c a | c -> a where empty :: c add :: a -> c -> c member :: a -> c -> Bool
A functional dependency
•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.
CS7120(Prasad) L51-Haskell 30
class MyFunctor f where
tmap :: (a -> b) -> f a -> 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))
CS7120(Prasad) L51-Haskell 31
Higher-Order Functions
•Functions are values in Haskell.
•“Program skeletons” take functions as parameters.
takeWhile :: (a -> Bool) -> [a] -> [a]takeWhile p [] = []takeWhile p (x:xs) | p x = x:takeWhile p xs | otherwise = []
Takes a prefix of a list, satisfying a predicate.
CS7120(Prasad) L51-Haskell 32
More Ways to Denote Functions
•below a b = b < a•takeWhile (below 10) [1,5,9,15,20]
•takeWhile (\b -> b < 10) [1,5,9,15,20]
•takeWhile (<10) [1,5,9,15,20]
“Lambda” expression.Function definition
in place.
Partial operatorapplication -- argument
replaces missing operand.
CS7120(Prasad) L51-Haskell 33
Lazy Evaluation
•Expressions are evaluated only when their value is really needed!
•Function arguments, data structure components, are held unevaluated until their value is used.
fib = 1 : 1 : [ a+b | (a,b)<- zip fib (tail fib) ]
nats = 0 : map (+1) nats
CS7120(Prasad) L51-Haskell 34
Non-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;
CS7120(Prasad) L51-Haskell 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.