Haskell Data TypesADTModules TypeClass Hierarchy Lazy Functional Language

  • Slides: 35
Download presentation
Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language Prasad CS 776 1

Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language Prasad CS 776 1

Modelling Alternatives New data types are useful to model values with several alternatives. Example:

Modelling Alternatives New data types are useful to model values with several alternatives. Example: Recording phone calls. type History = [(Event, Time)] type Time = Int The number called. data Event = Call String | Hangup Prasad CS 776 E. g. Call ” 031 -7721001”, Hangup, etc. 2

Extracting a List of Calls We can pattern match on values with components as

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)] calls ((Call number, start) : (Hangup, end) : history) = (number, start, end) : calls history calls [(Call number, start)] = [] -- a call is going on now calls [] = [] Prasad CS 776 3

Defining Recursive Data Types data Tree a = Node a (Tree a) | Leaf

Defining Recursive Data Types data Tree a = Node 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. Prasad CS 776 4

Pattern matching works as for lists. Tree Insertion Additional requirement insert. Tree : :

Pattern matching works as for lists. Tree Insertion Additional requirement insert. Tree : : Ord a => a -> Tree a insert. Tree x Leaf = Node x Leaf insert. Tree x (Node y l r) | x < y = Node y (insert. Tree x l) r | x > y = Node y l (insert. Tree x r) | x==y = Node y l r Prasad CS 776 5

Modelling Expressions Let’s design a datatype to model arithmetic expressions -- not their values,

Modelling Expressions Let’s design a datatype to model arithmetic expressions -- not their values, but their structure. An expression can be: data Expr = • a number n Num • a variable x |Var String • an addition a+b | Expr Add Expr | A recursive data. Expr type !! Mul Expr • a multiplication a*b Prasad CS 776 Int 6

Symbolic Differentiation Differentiating an expression produces a new expression. derive : : Expr ->

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 Variable to differentiate w. r. t. 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)) Prasad CS 776 7

Example d (2*x) = 2 dx derive (Mul (Num 2) (Var ”x”)) ”x” Add

Example d (2*x) = 2 dx derive (Mul (Num 2) (Var ”x”)) ”x” Add (Mul (Num 2) (derive (Var ”x”)) (Mul (Var ”x”) (derive (Num 2) ”x”)) Add (Mul (Num 2) (Num 1)) (Mul (Var ”x”) (Num 0)) 2*1 + x*0 Prasad CS 776 8

Formatting Expressions will be more readable if we convert them to strings. format. Expr

Formatting Expressions will be more readable if we convert them to strings. format. Expr : : Expr -> String format. Expr (Num n) = show n format. Expr (Var x) = x format. Expr (Add a b) = format. Expr a ++ ”+” ++ format. Expr b format. Expr (Mul a b) = format. Expr a ++ ”*” ++ format. Expr b format. Expr (Mul (Num 1) (Add (Num 2) (Num 3))) ” 1*2+3” Prasad CS 776 9

Quiz Which brackets are necessary? 1+(2+3) NO! 1+(2*3) NO! 1*(2+3) YES! What kind of

Quiz Which brackets are necessary? 1+(2+3) NO! 1+(2*3) NO! 1*(2+3) YES! What kind of expression may need to be bracketed? Additions When does it need to be bracketed? Inside multiplications. Prasad CS 776 10

Idea Give format. Expr an extra parameter, to tell it what context its argument

Idea Give format. Expr an extra parameter, to tell it what context its argument appears in. data Context = Multiply | Any. Other format. Expr (Add a b) Multiply = ”(” ++ format. Expr (Add a b) Any. Other ++ ”)” format. Expr (Mul a b) _ = format. Expr a Multiply ++ ”*” ++ format. Expr b Multiply Prasad CS 776 11

ADT and Modules Prasad CS 776 12

ADT and Modules Prasad CS 776 12

module construct in Haskell • Enables grouping a collection of related definitions • Enables

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 Prasad CS 776 13

module MTree ( Tree(Leaf, Branch), fringe ) where data Tree a = Leaf a

module MTree ( Tree(Leaf, Branch), fringe ) where data Tree a = Leaf a | Branch (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. Prasad CS 776 14

module Main (main) where import MTree ( Tree(Leaf, Branch), fringe ) main = do

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. Prasad CS 776 15

module Fringe(fringe) where import Tree(. . )) fringe : : Tree a -> [a]

module Fringe(fringe) where import Tree(. . )) fringe : : Tree a -> [a] -- A different definition of 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))) Prasad CS 776 16

Abstract Data Types module Tree. ADT (Tree, leaf, branch, cell, left, right, is. Leaf)

Abstract Data Types module Tree. ADT (Tree, leaf, branch, cell, left, right, is. Leaf) where data Tree a = Leaf a | Branch (Tree a) leaf = Leaf branch = Branch cell (Leaf a) = a left (Branch l r) = l right (Branch l r) = r is. Leaf (Leaf _) = True is. Leaf _ = False Prasad CS 776 17

Other features • Selective hiding import Prelude hiding length • Eliminating functions inherited on

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 = Mk. Q ([a], [a]) …operation implementation… – Use of Mk. Q-constructor prevents equality testing, printing, etc of queue values. Prasad CS 776 18

Treatment of Overloading through Type/Class Hierarchy Prasad CS 776 19

Treatment of Overloading through Type/Class Hierarchy Prasad CS 776 19

Kinds of functions • Monomorphic (defined over one type) capitalize : Char -> Char

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 -> Bool (==) : [(Int, Bool]] -> Bool Prasad CS 776 20

Overloading problem in SML fun add x y = x + y • SML-90

Overloading problem in SML fun add x y = x + y • SML-90 treats this definition as ambiguous: int -> int real -> real • SML-97 defaults it to: int -> int • Ideally, add defined whenever + is defined on a type. add : : (has. Plus a) => a -> a Prasad CS 776 21

Parametric vs ad hoc polymorphism • Polymorphic functions use the same definition at each

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

Class Hierarchy and Instance Declarations class Eq a => Ord a where (<), (<=),

Class Hierarchy and Instance Declarations class Eq a => Ord a where (<), (<=), (>) : : a -> Bool max, min : : 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. Prasad CS 776 23

Types of Overloaded Functions a may be any type in class Ord. insert :

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

Show and Read class Show a where show : : a -> String class

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. Prasad CS 776 25

Derived Instances data Tree a = Node a (Tree a) | Leaf deriving (Eq,

Derived Instances data Tree a = Node 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)) "Node 1 Leaf (Node 2 Leaf)" Prasad CS 776 26

Multi-Parameter Classes Define relations between classes. class Collection c a where empty : :

Multi-Parameter Classes Define relations between classes. class Collection c a where empty : : c add : : a -> c member : : a -> c -> Bool c is a collection with elements of type a. instance Eq a => Collection [a] a where empty = [] add = (: ) instance Ord a => member = elem Collection (Tree a) a where empty = Leaf add = insert. Tree member = elem. Tree Prasad CS 776 27

Multiple Inheritance class (Ord a, Show a) => a where … Sort. And. Print

Multiple Inheritance class (Ord a, Show a) => a where … Sort. And. Print function … Advanced Features: Module, … ADT, … Prasad CS 776 28

Functional Dependencies A functional dependency class Collection c a | c -> a where

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

class My. Functor f where tmap : : (a -> b) -> f a

class My. Functor f where tmap : : (a -> b) -> f a -> f b data Tree a = Branch (Tree a) | Leaf a deriving Show instance My. Functor Tree where tmap f (Leaf x) = Leaf (f x) tmap f (Branch t 1 t 2) = Branch (tmap f t 1) (tmap f t 2) tmap (*10) (Branch (Leaf 1) (Leaf 2)) Prasad CS 776 30

Higher-Order Functions • Functions are values in Haskell. • “Program skeletons” take functions as

Higher-Order Functions • Functions are values in Haskell. • “Program skeletons” take functions as parameters. take. While : : (a -> Bool) -> [a] take. While p [] = [] take. While p (x: xs) | p x = x: take. While p xs | otherwise = [] Takes a prefix of a list, satisfying a predicate. Prasad CS 776 31

More Ways to Denote Functions “Lambda” expression. Function definition in place. • take. While

More Ways to Denote Functions “Lambda” expression. Function definition in place. • take. While (b -> b < 10) [1, 5, 9, 15, 20] • below a b = b < a • take. While (below 10) [1, 5, 9, 15, 20] • take. While (<10) [1, 5, 9, 15, 20] Partial operator application -- argument replaces missing operand. Prasad CS 776 32

Lazy Evaluation fib = 1 : [ a+b | (a, b)<- zip fib (tail

Lazy Evaluation fib = 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 Prasad CS 776 33

Non-strict / Lazy Functional Language • Parameter passing mechanism – Call by name –

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; Prasad CS 776 34

 • Practical Benefits – Frees programmer from worrying about control issues: • Best

• 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. Prasad CS 776 35