Presentation is loading. Please wait.

Presentation is loading. Please wait.

PrasadCS7761 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language.

Similar presentations


Presentation on theme: "PrasadCS7761 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language."— Presentation transcript:

1 PrasadCS7761 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

2 PrasadCS7762 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 number called. E.g. Call ”031-7721001”, Hangup, etc.

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

4 PrasadCS7764 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 the components.

5 PrasadCS7765 Tree Insertion insertTree :: Ord a => a -> Tree a -> Tree a insertTree x Leaf = Node x Leaf Leaf insertTree 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 Pattern matching works as for lists. Additional requirement

6 PrasadCS7766 Modelling Expressions Let’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 = NumInt |VarString |AddExpr Expr |MulExpr Expr A recursive data type !!

7 PrasadCS7767 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 to differentiate w.r.t.

8 PrasadCS7768 Example d (2*x) = 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)) 2*1 + x*0

9 PrasadCS7769 Formatting Expressions Expressions 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

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

11 PrasadCS77611 Idea 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 PrasadCS77612 ADT and Modules

13 PrasadCS77613 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

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

15 PrasadCS77615 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 PrasadCS77616 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)) )

17 PrasadCS77617 Abstract 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

18 PrasadCS77618 Other 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 PrasadCS77619 Treatment of Overloading through Type/Class Hierarchy

20 PrasadCS77620 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

21 PrasadCS77621 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

22 PrasadCS77622 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. Class methods and types. Default definition. Read: “ a is a type in class Eq, if it has the following methods”.

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

24 PrasadCS77624 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 type in class Ord. Because insert uses a method from class Ord. f :: (Eq a) => a -> [a] -> Int f x y = if x==y then 1 else 2

25 PrasadCS77625 Show and Read class Show a where show :: a -> String class Read a where read :: String -> a These are definitions are simplifications: there are more methods in reality. read. show = id (usually)

26 PrasadCS77626 Derived 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. Main> show (Node 1 Leaf (Node 2 Leaf Leaf)) "Node 1 Leaf (Node 2 Leaf Leaf)"

27 PrasadCS77627 Multi-Parameter Classes Define 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

28 PrasadCS77628 Multiple Inheritance class (Ord a, Show a) => a where … SortAndPrint function … Advanced Features: Module, … ADT, …

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

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

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

32 PrasadCS77632 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 operator application -- argument replaces missing operand.

33 PrasadCS77633 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

34 PrasadCS77634 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;

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


Download ppt "PrasadCS7761 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language."

Similar presentations


Ads by Google