1 / 35

Haskell

Haskell. Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language. 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

scot
Download Presentation

Haskell

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

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

  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 [] = [] CS776

  4. Defining 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. CS776

  5. Tree Insertion Pattern matching works as for lists. Additional requirement 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 CS776

  6. 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 = Num Int |Var String | Add Expr Expr | Mul Expr Expr A recursive data type !! CS776

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

  8. 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 CS776

  9. 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 CS776

  10. Quiz NO! 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! Additions Inside multiplications. CS776

  11. 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 CS776

  12. ADT and Modules CS776

  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 CS776

  14. module MTree ( Tree(Leaf,Branch), fringe )  wheredata 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. CS776

  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. CS776

  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 =  doprint (fringe (Branch (Leaf 1) (Leaf 2)))      print(Fringe.fringe(Branch (Leaf 1) (Leaf 2))) CS776

  17. 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 CS776

  18. 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. CS776

  19. Treatment of Overloading through Type/Class Hierarchy CS776

  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 CS776

  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 CS776

  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 name. class Eq a where (==) :: a -> a -> Bool (/=) :: a -> a -> Bool x/=y = not (x==y) Read: “a is a type in class Eq, if it has the following methods”. Class methods and types. Default definition. CS776

  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. CS776

  24. Types of Overloaded Functions a may be any type in classOrd. insert :: Ord a => a -> [a] -> [a] insert x [] = [] insert x (y:xs) | x<=y = x:y:xs | x>y = y:insert x xs f :: (Eq a) => a -> [a] -> Int f x y = if x==y then 1 else 2 Because insert uses a method from class Ord. CS776

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

  26. 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)" CS776

  27. 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 CS776

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

  29. Functional Dependencies A functional dependency class Collection c a | c -> a where empty :: c add :: a -> c -> c member :: a -> c -> 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. CS776

  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)) CS776

  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. CS776

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

  33. Lazy Evaluation fib = 1 : 1 : [ a+b | (a,b)<- 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 CS776

  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; CS776

  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. CS776

More Related