cs7120(prasad)l51-haskell1 haskell data types/adt/modules type/class hierarchy lazy functional...

35
CS7120(Prasad) L51-Haskell 1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

Upload: neal-walker

Post on 18-Jan-2016

225 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

CS7120(Prasad) L51-Haskell 1

Haskell

Data Types/ADT/Modules

Type/Class Hierarchy

Lazy Functional Language

Page 2: CS7120(Prasad)L51-Haskell1 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.

Page 3: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 4: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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.

Page 5: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 6: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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 !!

Page 7: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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.

Page 8: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 9: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 10: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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.

Page 11: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 12: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

CS7120(Prasad) L51-Haskell 12

ADT and Modules

Page 13: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 14: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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.

Page 15: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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.

Page 16: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 17: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 18: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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.

Page 19: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

CS7120(Prasad) L51-Haskell 19

Treatment of Overloading through Type/Class Hierarchy

Page 20: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 21: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 22: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 23: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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.

Page 24: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 25: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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)

Page 26: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 27: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 28: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

CS7120(Prasad) L51-Haskell 28

Multiple Inheritance

class (Ord a, Show a) => a where…

SortAndPrint function…

Advanced Features:Module, …ADT, …

Page 29: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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.

Page 30: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 31: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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.

Page 32: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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.

Page 33: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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

Page 34: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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;

Page 35: CS7120(Prasad)L51-Haskell1 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language

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.