CITS3211 FUNCTIONAL PROGRAMMING 4....

14
CITS3211 FUNCTIONAL PROGRAMMING 4. Types Summary: This lecture discusses the Haskell type system, including parametric polymorphism and ad-hoc polymorphism using type classes. CITS3211 Functional Programming 1 4. Types

Transcript of CITS3211 FUNCTIONAL PROGRAMMING 4....

Page 1: CITS3211 FUNCTIONAL PROGRAMMING 4. Typesteaching.csse.uwa.edu.au/units/CITS3211/lectureNotes/02/04.pdf · influenced by functional programming (notable recently: the addition of parametric

CITS3211

FUNCTIONAL PROGRAMMING

4. Types

Summary:   This   lecture   discusses   the   Haskell   type   system, including parametric polymorphism and ad­hoc polymorphism using type classes.

CITS3211 Functional Programming 1 4. Types

Page 2: CITS3211 FUNCTIONAL PROGRAMMING 4. Typesteaching.csse.uwa.edu.au/units/CITS3211/lectureNotes/02/04.pdf · influenced by functional programming (notable recently: the addition of parametric

Types in Functional Programming

● Languages   can   be   divided   into   one   of   two   classes: dynamically typed and statically typed.

Statically typed languages perform type checking prior to program execution.

Dynamically typed languages do not.

● Modern functional languages (like Haskell, ML and OCaml) are   often   statically   typed,   with   particularly   sophisticated type   systems,   however   LISP   and   related   languages   are dynamically typed.

● Static typing can be particularly powerful and useful  in a functional language because functions only map from inputs to  outputs,   and   types  can  describe  exactly  what  kinds  of inputs and outputs are allowed. 

● Static typing allows a majority errors to be quickly caught and fixed. 

● It also allows a lot of the basic structure of the program to be made explicit by the programmer.

CITS3211 Functional Programming 2 4. Types

Page 3: CITS3211 FUNCTIONAL PROGRAMMING 4. Typesteaching.csse.uwa.edu.au/units/CITS3211/lectureNotes/02/04.pdf · influenced by functional programming (notable recently: the addition of parametric

Types in Functional Programming 

● Types in functional languages have a long history: concepts like parametric polymorphism have been studied in typed λ­calculus since the 1930s.

● Type   systems   for   other   languages   have   been   highly influenced by functional programming (notable recently: the addition of parametric polymorphism to Java and C#). 

● Much current research in functional programming concerns even more sophisticated type systems. 

● This topic focuses only what is in Haskell, but we will come back to types later in the unit.

CITS3211 Functional Programming 3 4. Types

Page 4: CITS3211 FUNCTIONAL PROGRAMMING 4. Typesteaching.csse.uwa.edu.au/units/CITS3211/lectureNotes/02/04.pdf · influenced by functional programming (notable recently: the addition of parametric

Type synonyms

• A new name for an old type• Used principally to enhance the readability of a program

type Name = String

type Address = [String]

type Day = Int

type Month = Int

type Year = Int

type Date = (Day, Month, Year)

CITS3211 Functional Programming 4 4. Types

Page 5: CITS3211 FUNCTIONAL PROGRAMMING 4. Typesteaching.csse.uwa.edu.au/units/CITS3211/lectureNotes/02/04.pdf · influenced by functional programming (notable recently: the addition of parametric

Enumerated datatypes

• A datatype which is defined by listing all possible values of the type− cf. Bool

• A   datatype   to   represent   the   days   of   the   week   might   be defined by

data Day = Mon | Tues | Wed | Thurs | Fri | Sat | Sun

• Day is a new type, with seven possible values• Mon,   etc.  are  constructors,  which  can  be  used  anywhere 

that any other values can be used− constructors can be used in expressions and in patterns

• Both  type­names and constructor­names must  start  with a capital letter

CITS3211 Functional Programming 5 4. Types

Page 6: CITS3211 FUNCTIONAL PROGRAMMING 4. Typesteaching.csse.uwa.edu.au/units/CITS3211/lectureNotes/02/04.pdf · influenced by functional programming (notable recently: the addition of parametric

Composite datatypes

• A datatype whose values contain values of other types− cf. tuple types

• A datatype   to   represent   the   roots  of  a  quadratic  equation might be defined by

type Complex = (Float, Float)

data Roots = Onereal Float| Tworeals Float Float| Onecomplex Complex| Twocomplex Complex Complex

• Complex is a type synonym• Roots  is a new type and  Onereal, Tworeals, Onecomplex

and Twocomplex are constructor functions− Onereal has type Float -> Roots

− Tworeals has type Float -> Float -> Roots

− Onecomplex has type Complex -> Roots

− Twocomplex has type Complex -> Complex -> Roots

• Constructor functions can be used anywhere that any other functions can be used

mkroots :: [Float] -> [Roots]

mkroots xs = [Onereal x | x <- xs]

CITS3211 Functional Programming 6 4. Types

Page 7: CITS3211 FUNCTIONAL PROGRAMMING 4. Typesteaching.csse.uwa.edu.au/units/CITS3211/lectureNotes/02/04.pdf · influenced by functional programming (notable recently: the addition of parametric

Recursive datatypes

• A datatype whose values contain values of the same type− cf. lists

• A datatype   to   represent  binary   trees  of   integers  might  be defined by

data Inttree = Leaf Int | Branch Inttree Int Inttree

• Inttree  is a new type and  Leaf  and  Branch  are constructor functions− Leaf has type Int -> Inttree

− Branch has type Inttree -> Int -> Inttree -> Inttree

• Functions over composite and recursive datatypes are often defined by cases using pattern­matching

CITS3211 Functional Programming 7 4. Types

Page 8: CITS3211 FUNCTIONAL PROGRAMMING 4. Typesteaching.csse.uwa.edu.au/units/CITS3211/lectureNotes/02/04.pdf · influenced by functional programming (notable recently: the addition of parametric

Haskell type­inference

• When a program is submitted for compilation, the Haskell system− infers   the  most  general  type  of  each function  in  the 

program, and− checks that the type declaration given for each function 

is not more general than the inferred type• We   will   be   studying   type­inference   algorithms   later   in 

CITS3211• A function’s declaration is allowed to “over­constrain” the 

function, but it is not allowed to “under­constrain” it, e.g.

f (n, x) = n /= ‘x’

f :: (Char, a) -> Boolis the most general type

f :: (Char, String) -> Boolis OK: over­constrained(but not usually desirable)

f :: (b, a) -> Boolis not OK: under­constrained

• Here, a and b are type variables: they denote any type

CITS3211 Functional Programming 8 4. Types

Page 9: CITS3211 FUNCTIONAL PROGRAMMING 4. Typesteaching.csse.uwa.edu.au/units/CITS3211/lectureNotes/02/04.pdf · influenced by functional programming (notable recently: the addition of parametric

Polymorphic functions

• Some functions  can  take  arguments  of  any  type,  e.g.  fst

returns the first element of any 2­tuple

fst :: (a, b) -> a

fst (x, y) = x

• Again, a and b are type variables: they denote any type•Type variables must start with a small letter•A   function   that   operates   over   more   than   one   type   is   a 

polymorphic function• All occurrences of a type variable a (or b, or whatever) in a 

given context denote the same type

flip :: (a -> b -> c) -> b -> a -> c

flip f x y = f y x

flip (–) 4 15 is OK

flip (&&) False True is OK

flip elem [1 .. 8] 35 is OK

flip (&&) 4 True is not OK

CITS3211 Functional Programming 9 4. Types

Page 10: CITS3211 FUNCTIONAL PROGRAMMING 4. Typesteaching.csse.uwa.edu.au/units/CITS3211/lectureNotes/02/04.pdf · influenced by functional programming (notable recently: the addition of parametric

Polymorphic datatypes

• Lists can contain elements of any type− the formal declaration of lists is given by

data [a] = [] | a : [a]

• User­defined  datatypes  can  also  contain  elements  of  any type

data Inttree = Leaf Int | Branch Inttree Int Inttree

data Gentree a = Leaf a | Branch (Gentree a) a (Gentree a)

• Gentree is a type­constructor− type­constructors can have any number of arguments− type­constructors must  always be applied  to  the right 

number of arguments

CITS3211 Functional Programming 10 4. Types

Page 11: CITS3211 FUNCTIONAL PROGRAMMING 4. Typesteaching.csse.uwa.edu.au/units/CITS3211/lectureNotes/02/04.pdf · influenced by functional programming (notable recently: the addition of parametric

Categories of functions

• not is a function which is monomorphic

not :: Bool -> Bool

− not can be applied to values of only one type• length is a function which is parametrically polymorphic

length :: [a] -> Int

− length can be applied to values of an infinite number of types

− length  behaves   in   exactly   the   same  way  with   all   of these types

• * is   a   function   which   is  ad­hoc   polymorphic  or overloaded

(*) :: Int -> Int -> Int

(*) :: Float -> Float -> Float

− * can be applied to values of a finite number n of types, where n > 1

− * behaves differently with different types• * works on types in the type class Num

CITS3211 Functional Programming 11 4. Types

Page 12: CITS3211 FUNCTIONAL PROGRAMMING 4. Typesteaching.csse.uwa.edu.au/units/CITS3211/lectureNotes/02/04.pdf · influenced by functional programming (notable recently: the addition of parametric

Example

• What is the most general type of sqr?

sqr x = x * x

• We want  sqr  to work for any type that has  * defined, e.g. Int, Integer, Float, Double, etc− but not for Char, Bool, [Int], etc

sqr :: Num a => a -> a

• The class Num is defined by (this is a cut­down version)

class Num a where

(+), (–), (*) :: a -> a -> a

negate :: a -> a

x – y = x + negate y

• Int  and  Float  (and others) are  instances  (i.e. members) of Num, e.g.

instance Num Int where

(+) = primIntPlus

(*) = primIntMultiply

negate = primIntNegate

CITS3211 Functional Programming 12 4. Types

Page 13: CITS3211 FUNCTIONAL PROGRAMMING 4. Typesteaching.csse.uwa.edu.au/units/CITS3211/lectureNotes/02/04.pdf · influenced by functional programming (notable recently: the addition of parametric

Type classes

• Haskell has many pre­defined type classes− many   of   the   pre­defined   functions   and  operators   are 

valid only for types in certain type classes• Eq: types that have equality defined

− ==, /=• Ord: types that have an ordering defined

− total orders− <, <=, >, >=, min, max, compare

• Enum: enumerated datatypes− can be used in arithmetic series− toEnum and fromEnum (chr/decode and ord/code)

• Show: types that have a printing function defined− show :: Show a => a -> String

• Read: types that have a parsing function defined− read :: Read a => String -> a

• Bounded: finite types with a smallest and largest value− minBound, maxBound :: Bounded a => a

• Other classes are described in the Haskell report• The   pre­defined   classes   are   defined   in   a   multiple­

inheritance hierarchy

CITS3211 Functional Programming 13 4. Types

Page 14: CITS3211 FUNCTIONAL PROGRAMMING 4. Typesteaching.csse.uwa.edu.au/units/CITS3211/lectureNotes/02/04.pdf · influenced by functional programming (notable recently: the addition of parametric

Derived instances

• When   you   declare   a   new   datatype,   the   system   can automatically derive functions in the pre­defined classes

data Gentree a = Leaf a | Branch (Gentree a) a (Gentree a)

deriving (Eq, Show)

− given this declaration, the system will define equality functions  (==,  /=)  and printing  functions  (show)   for Gentree

• You will  nearly always want to do this  (and remember you may want functions in other classes derived too)− the principal exceptions will be

− when you define an abstract datatype− when you want to override the default definitions 

(e.g. for read/show/==/whatever)

CITS3211 Functional Programming 14 4. Types