cs5205haskell1 cs5205: foundations in programming languages fp with haskell a pure lazy functional...

43
CS5205 Haskell 1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language design.

Upload: samson-tate

Post on 05-Jan-2016

228 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 1

CS5205: Foundations in Programming Languages

FP with Haskell

A pure lazy functional language that embodies many innovative ideas in language design.

Page 2: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 2

Haskell Haskell

• Advanced programming language – reusable, abstract, efficient, feature-rich.

• Functions and Expressions• Values, Types and Lazy evaluation• Products, Records and Algebraic Types• Polymorphic Types & Type Classes• Higher-Order Functions• Infix operator and sections.

Reference --- A Gentle Introduction to Haskell 98 http://www.haskell.org/tutorial

Page 3: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 3

Functions Functions

• Function is a black box that converts input to output. A basis of software component.

function

…. inputs

…. output

pure

function

…. inputs

…. output

impure

globalvars

Page 4: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 4

Example of FunctionsExample of Functions

• Double a given input.

square :: Int -> Int

square x = x*x

• Conversion from fahrenheit to celcius

fahr_to_celcius :: Float -> Float

fahr_to_celcius temp = (temp – 32)/1.8

• A function with multiple results - quotient & remainder

divide :: Int -> Int -> (Int,Int)

divide x y = (div x y, mod x y)

Page 5: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 5

Expression-OrientedExpression-Oriented

• Instead of command/statement : if e1 then stmt1 else stmt2

• Instead of imperative commands/statements, the focus is on expression.

• We use conditional expressions :if e1 then e2 else e3

Page 6: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 6

Expression-OrientedExpression-Oriented

• An example function:

fact :: Integer -> Integerfact n = if n=0 then 1

else n * fact (n-1)

• Can use pattern-matching instead of conditional

fact 0 = 1 fact n = n * fact (n-1)

fact n = case n of 0 -> 1 a -> a * fact (a-1)

• Alternatively:

Page 7: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 7

Conditional Conditional Case Construct Case Construct

• Can be translated tocase e1 of True -> e2 False -> e3

• Conditional;if e1 then e2 else e3

length xs = case xs of [] -> 0;

y:ys -> 1+(length ys)

• Case also works over data structures (without any extra primitives)

Locally bound variables

Page 8: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 8

Lexical Scoping Lexical Scoping

let y = a+bf x = (x+y)/y

in f c + f d

• Local variables can be created by let construct to give nested scope for the name space. Example:

• For scope bindings over guarded expressions, we require a where construct instead:

f x y | x>z = …| y==z = …| y<z = ….

where z=x*x

Page 9: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 9

Layout Rule Layout Rule

is being parsed as:

• Haskell uses two dimensional syntax that relies on declarations being “lined-up columnwise”

• Rule : Next character after keywords where/let/of/do determines the starting columns for declarations. Starting after this point continues a declaration, while starting before this point terminates a declaration.

let y = a+bf x = (x+y)/y

in f c + f d

let { y = a+b; f x = (x+y)/y }

in f c + f d

Page 10: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 10

Expression EvaluationExpression Evaluation

• Expression can be computed (or evaluated) so that it is reduced to a value. This can be represented as:

e .. v

• A concrete example of this is:

inc (inc 3) inc (4) 5

• Type preservation theorem says that:

if e :: t Æ e v , it follows that v :: t

e * v

• We can abbreviate above as:

Page 11: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 11

Values and TypesValues and Types

• As a purely functional language, all computations are done via evaluating expressions (syntactic sugar) to yield values (normal forms as answers).

• Each expression has a type which denotes the set of possible outcomes.

• v :: t can be read as value v has type t.• Examples of typings, associating a value with its

corresponding type are:

5 :: Integer'a' :: Char[1,2,3] :: [Integer]('b', 4) :: (Char, Integer)“cs5” :: String (same as [Char])

Page 12: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 12

Built-In TypesBuilt-In Types

data Char = ‘a’ | ‘b’ | …data Int = -65532 | … | -1 | 0 | 1 | …. | 65532 data Integer = … | -2 | -1 | 0 | 1 | 2 | …

• They are not special:

• Tuples are also built-in.

data (a,b) = M2(a,b)data (a,b,c) = M3(a,b,c)data (a,b.c.d) = M4(a,b,c,d)

• List type uses an infix operator:

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

[1,2,3] is short hand for 1 : (2 : (3 : []))

Page 13: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 13

User-Defined Algebraic TypesUser-Defined Algebraic Types

data Bool = False | Truedata Color = Red | Green | Blue | Violet

• Can describe enumerations:

• Pt is a data constructor with type a -> a -> Point a

Pt 2.0 3.1 :: Point FloatPt ‘a’ ‘b’ :: Point CharPt True False :: Point Bool

• Can also describe a tuple

data Pair = P2 Integer Integerdata Point a = Pt a a

type variable

Page 14: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 14

Recursive TypesRecursive Types

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

• Some types may be recursive:

• Two data constructors:

Leaf :: a -> Tree aBranch :: Tree a -> Tree a -> Tree a

• An example function over recursive types:

fringe :: Tree a -> [a]

fringe (Leaf x) = [x]fringe (Branch left right) = (fringe left) ++

(fringe right)

Page 15: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 15

Polymorphic TypesPolymorphic Types

• Support types that are universally quantified in some way over all types.

• 8 c. [c] denotes a family of types, for every type c, the type of lists of c.

• Covers [Integer], [Char], [Integer->Integer], etc.

• Polymorphism help support reusable code, e.g

length :: 8 a. [a] -> Integerlength [] = 0length (x:xs) = 1 + length xs

Page 16: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 16

Polymorphic TypesPolymorphic Types

length [1,2,3] ) 2length [‘a’, ’b’, ‘c’] ) 3length [[1],[],[3]] ) 3

• This polymorphic function can be used on list of any type..

• More examples :

head :: [a] -> ahead (x:xs) = x

tail :: [a] -> [a]tail (x:xs) = xs

• Note that head/tail are partial functions, while length is a total function?

Page 17: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 17

Principal TypesPrincipal Types

• An expression’s principal type is the least general type that contains all instances of the expression.

• For example, the principal type of head function is [a]->a, while [b] -> a, b -> a, a are correct but too general but [Integer] -> Integer is too specific.

• Principal type can help supports software reusability with accurate type information.

[Char] <: 8 a. [a] <: 8 a. a

• Some types are more general than others:

Page 18: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 18

Type SynonymsType Synonyms

type String = [Char]type Person = (Name, Address)type Name = Stringdata Address = None | Addr String

• It is possible to provide new names for commonly used types

• Type synonyms do not define new types, but simply give new names for existing types.

type AssocList a b = [(a,b)]

• Their use can improve code readability.

Page 19: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 19

Type Classes and OverloadingType Classes and Overloading

• Parametric polymorphism works for all types. However, ad-hoc polymorphism works for a class of types and can systematically support overloading.

• For example, what is the type for (+) operator?

(+) :: a -> a -> a

(+) :: Int -> Int -> Int (+) :: Float -> Float -> Float

• What about methods built from (+)?double x = x+x

• Better solution is to use a type class for numerics! (+) :: Num a => a -> a -> a double :: Num a => a -> a

Page 20: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 20

Equality ClassEquality Class

• Similar issue with equality. Though it looks like:

(==) :: a -> a -> Bool

• Equality can be tested for data structures but not functions!

• Solution is to define a type class that supports the equality method, as follows:

class Eq a where(==),(/=) :: a -> a -> Boolx /= y = not (x==y)

• Then: (==) :: Eq a => a -> a -> Bool

default definition

Page 21: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 21

Members of Eq Type ClassMembers of Eq Type Class

• The class is open and can be extended, as follows:

instance Eq Integer wherex == y = x ‘integerEq’ y

• Recursive type can also be handled but elements may need to be given type qualifiers.

instance (Eq a) => Eq (Tree a) whereLeaf a == Leaf b = a==b(Branch l1 r1) == (Branch l2 r2)

= (l1==l2) && (r1==r2)_ == _ = False

instance Eq Float wherex == y = x ‘FloatEq’ y

Page 22: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 22

More Members of Eq Type ClassMore Members of Eq Type Class

• Similarly, we may use structural equality for List:

• One use of Eq class is:

instance (Eq a) => Eq ([a]) where[] == [] = True(x:xs) == (y:ys) = (x==y) && (xs==ys)_ == _ = False

• Exercise : define Set as an instance of the Eq class.

elem :: (Eq a) => a -> [a] -> Boolx ‘elem’ [] = Falsex ‘elem’ (y:ys) = (x==y) || (x ‘elem’ ys)

Page 23: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 23

Numeric ClassNumeric Class

• There is a hierarchy of numeric classes. Most basic is:

class Num a where (+),(-),(*) :: a -> a -> a negate,abs,signum :: a -> a fromInteger :: Integer -> a

x – y = x + (negate y) negate x = 0 – x

instance Num Int where …instance Num Integer where …instance Num Float where …instance Num Double where …

Page 24: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 24

Functions and its TypeFunctions and its Type

• Method to increment its input

inc x = x+1

• Or through lambda expression (anonymous functions)

(\ x -> x+1)

• They can also be given suitable function typing:

inc :: Num a => a -> a(\x -> x+1) :: Num a => a -> a

• Types can be user-supplied or inferred.

Page 25: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 25

Functions and its TypeFunctions and its Type

• Some examples

(\x -> x+1) 3.2

• User can restrict the type, e.g.

inc :: Int -> Int

(\x -> x+1) 3

• In that case, some examples may be wrongly typed.

inc 3.2

inc 3

Page 26: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 26

Function AbstractionFunction Abstraction

• Function abstraction is the ability to convert any expression into a function that is evaluated at a later time.

<Expr>

Normal Execution

time

p = \ () -> Expr

p ()

Delayed Execution

time

Page 27: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 27

Higher-Order FunctionsHigher-Order Functions

• Higher-order programming treats functions as first-class, allowing them to be passed as parameters, returned as results or stored into data structures.

• This concept supports generic coding, and allows programming to be carried out at a more abstract level.

• Genericity can be applied to a function by letting specific operation/value in the function body to become parameters.

Page 28: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 28

FunctionsFunctions

• The first version allows a function to be returned as result after applying a single argument.

add2 :: (Integer,Integer) -> Integeradd2(x,y) = x+y

• Functions can be written in two main ways:

add :: Integer -> Integer -> Integeradd x y = x+y

inc :: Integer -> Integerinc = add 1

• The second version needs all arguments. Same effect requires a lambda abstraction:

inc = \ x -> add2(x,1)

Page 29: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 29

FunctionsFunctions

• Functions can also be passed as parameters. Example:

map :: (a->b) -> [a] -> [b]map f [] = []map f (x:xs) = (f x) : (map f xs)

• Alternative ways of defining functions:

add = \ x -> \ y -> x+yadd = \ x y -> x+y

• Such higher-order function aids code reuse.

map (add 1) [1, 2, 3] ) [2, 3, 4]map add [1, 2, 3] ) [add 1, add 2, add 3]

Page 30: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 30

GenericityGenericity• Replace specific entities (0 and +) by parameters.

sumList ls = case ls of [] -> 0 x:xs -> x+(sumList xs)

foldr f u ls = case ls of [] -> u x:xs -> f x (foldr f u xs)

Page 31: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 31

Polymorphic, Higher-Order TypesPolymorphic, Higher-Order Types

sumList :: [Int] -> Int

sumList :: Num a => [a] -> a

foldr :: (a -> b -> b) -> b -> [a] -> b

Page 32: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 32

Instantiating Generic FunctionsInstantiating Generic Functions

sumL2 :: Num a => [a] -> asumL2 ls = foldr (+) 0 ls

sumL2 [1, 2, 3] )

sumL2 [1.1, 3, 2.3] )

Page 33: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 33

Instantiating Generic FunctionsInstantiating Generic Functions

prodL :: Num a => [a] -> aprodL ls = foldr (*) 1 ls

prodL [1, 2, 5] )

prodL [1.1, 3, 2.3] )

Page 34: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 34

Instantiating Generic FunctionsInstantiating Generic Functions

map :: (a -> b) -> [a] -> [b]map f [] = []map f (x:xs) = (f x) : (map f xs)

map f xs = foldr … … … xs

• Can you express map in terms of foldr?

Page 35: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 35

Instantiating Generic FunctionsInstantiating Generic Functions

filter :: (a -> Bool) -> [a] -> [a]filter f [] = []filter f (x:xs) =

if (f x) then x : (filter f xs)else x : filter f xs

• Filtering a list of elements with a predicate.

filter f xs = foldr … … … xs

• Can we express filter in terms of foldr?

Page 36: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 36

Pipe/ComposePipe/Compose

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

compose f g = \ x -> f (g x)g | f = compose f g

cmd1 | cmd2

• Similar to Unix pipe command:

Page 37: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 37

Iterator Construct Iterator Construct

for :: Int -> Int -> (Int -> a -> a) -> a -> a

for i j f a = if i>j then aelse f (i+1) j (f i a)

for :: Num b, Ord b => b -> b ->(b -> a -> a) -> a -> a

• In Haskell, type class help give a more generic type:

Page 38: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 38

Right Folding Right Folding

foldr f u [x1,x2,..,xn]

f x1 (foldr f u [x2 ..xn]) f x1 (f x2 (fold f u [x3..xn]))

f x1 (f x2 (… (fold f u [xn]) …)) f x1 (f x2 (… (f xn u) …)))

associate to right

Page 39: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 39

Left Folding – Tail Recursion Left Folding – Tail Recursion

• Accumulate result in a parameter:

foldl f u ls = case ls of [] -> u x:xs -> foldl f (f u x) xs

• What is the type of foldl?

• Can we compute factorial using it?

based on accumulation

Page 40: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 40

Left Folding Left Folding

foldl f u [x1,x2,..,xn]

foldl f (f u x1) [x2 ..xn] foldl f (f (f u x1) x2) [x3..xn]))

foldl f (f … (f (f u x1) x2)… xn) [] f (… (f (f u x1) x2) …) xn

left is here!

Page 41: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 41

Instance of Left FoldingInstance of Left Folding• Summing a list by accumulation.

sumT acc ls = case ls of [] -> 0 x:xs -> sumT (x+acc) xs

sumList ls = sumT 0 ls

sumT acc ls = foldl (+) acc ls

Page 42: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 42

Infix OperatorInfix Operator

• Another example is function composition.

• Infix operators are distinguished entirely by symbols:

(++) :: [a]-> [a] -> [a][] ++ ys = ys(x:xs) ++ ys = x : (xs ++ ys)

• Infix operator can be coerced to prefix by bracketing, e.g. map (+) [1,2,3]

(.) :: (b->c) -> (a->b) -> (a->c)f . g = \ x -> f (g x)

• Alphanumeric named function can be made infix too, e.g. a ‘add’ b x ‘elem’ xs

Page 43: CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language

CS5205 Haskell 43

SectionsSections

• Other examples:.

• Infix operators can also be partially applied:

(x+) ´ \y -> x+y(+y) ´ \x -> x+y(+) ´ \x y -> x+y

• These are syntactic sugar for programming conveniences.

inc = (+ 1)add = (+)