Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language."— Presentation transcript:

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

2 CS5205Haskell2 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

3 CS5205Haskell3 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 global vars

4 CS5205Haskell4 Example of Functions Example 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)

5 CS5205Haskell5 Expression-Oriented Expression-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

6 CS5205Haskell6 Expression-Oriented Expression-Oriented An example function: fact :: Integer -> Integer fact 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:

7 CS5205Haskell7 Conditional  Case Construct Can be translated to case 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

8 CS5205Haskell8 Lexical Scoping Lexical Scoping let y = a+b f 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

9 CS5205Haskell9 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+b f x = (x+y)/y in f c + f d let { y = a+b ; f x = (x+y)/y } in f c + f d

10 CS5205Haskell10 Expression Evaluation Expression 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:

11 CS5205Haskell11 Values and Types Values 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])

12 CS5205Haskell12 Built-In Types Built-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 : []))

13 CS5205Haskell13 User-Defined Algebraic Types User-Defined Algebraic Types data Bool = False | True data 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 Float Pt ‘a’ ‘b’:: Point Char Pt True False:: Point Bool Can also describe a tuple data Pair = P2 Integer Integer data Point a = Pt a a type variable

14 CS5205Haskell14 Recursive Types Recursive Types data Tree a = Leaf a | Branch (Tree a) (Tree a) Some types may be recursive: Two data constructors: Leaf :: a -> Tree a Branch:: 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)

15 CS5205Haskell15 Polymorphic Types Polymorphic 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] -> Integer length [] = 0 length (x:xs)= 1 + length xs

16 CS5205Haskell16 Polymorphic Types Polymorphic Types length [1,2,3] ) 2 length [‘a’, ’b’, ‘c’] ) 3 length [[1],[],[3]] ) 3 This polymorphic function can be used on list of any type.. More examples : head :: [a] -> a head (x:xs)= x tail :: [a] -> [a] tail (x:xs)= xs Note that head/tail are partial functions, while length is a total function?

17 CS5205Haskell17 Principal Types Principal 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:

18 CS5205Haskell18 Type Synonyms Type Synonyms type String = [Char] type Person = (Name, Address) type Name = String data 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.

19 CS5205Haskell19 Type Classes and Overloading Type 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

20 CS5205Haskell20 Equality Class Equality 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 -> Bool x /= y= not (x==y) Then: (==) :: Eq a => a -> a -> Bool default definition

21 CS5205Haskell21 Members of Eq Type Class Members of Eq Type Class The class is open and can be extended, as follows: instance Eq Integer where x == 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) where Leaf a == Leaf b= a==b (Branch l1 r1) == (Branch l2 r2) = (l1==l2) && (r1==r2) _ == _= False instance Eq Float where x == y= x ‘FloatEq’ y

22 CS5205Haskell22 More Members of Eq Type Class More 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] -> Bool x ‘elem’ []= False x ‘elem’ (y:ys)= (x==y) || (x ‘elem’ ys)

23 CS5205Haskell23 Numeric Class Numeric 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 …

24 CS5205Haskell24 Functions and its Type Functions 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.

25 CS5205Haskell25 Functions and its Type Functions 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 

26 CS5205Haskell26 Function Abstraction Function Abstraction Function abstraction is the ability to convert any expression into a function that is evaluated at a later time. Normal Execution time p = \ () ->  Expr  p () Delayed Execution time

27 CS5205Haskell27 Higher-Order Functions Higher-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.

28 CS5205Haskell28 Functions Functions The first version allows a function to be returned as result after applying a single argument. add2 :: (Integer,Integer) -> Integer add2(x,y) = x+y Functions can be written in two main ways: add :: Integer -> Integer -> Integer add x y = x+y inc :: Integer -> Integer inc = add 1 The second version needs all arguments. Same effect requires a lambda abstraction: inc = \ x -> add2(x,1)

29 CS5205Haskell29 Functions Functions 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+y add= \ 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]

30 CS5205Haskell30 Genericity Genericity 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)

31 CS5205Haskell31 Polymorphic, Higher-Order Types Polymorphic, Higher-Order Types sumList :: [Int] -> Int sumList :: Num a => [a] -> a foldr :: (a -> b -> b) -> b -> [a] -> b

32 CS5205Haskell32 Instantiating Generic Functions Instantiating Generic Functions sumL2 :: Num a => [a] -> a sumL2 ls = foldr (+) 0 ls sumL2 [1, 2, 3] ) sumL2 [1.1, 3, 2.3] )

33 CS5205Haskell33 Instantiating Generic Functions Instantiating Generic Functions prodL :: Num a => [a] -> a prodL ls = foldr (*) 1 ls prodL [1, 2, 5] ) prodL [1.1, 3, 2.3] )

34 CS5205Haskell34 Instantiating Generic Functions Instantiating 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 ?

35 CS5205Haskell35 Instantiating Generic Functions Instantiating 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 ?

36 CS5205Haskell36 Pipe/Compose Pipe/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:

37 CS5205Haskell37 Iterator Construct Iterator Construct for :: Int -> Int -> (Int -> a -> a) -> a -> a for i j f a = if i>j then a else 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:

38 CS5205Haskell38 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

39 CS5205Haskell39 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

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

41 CS5205Haskell41 Instance of Left Folding Instance 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

42 CS5205Haskell42 Infix Operator Infix 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’ bx ‘elem’ xs

43 CS5205Haskell43 Sections Sections 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=(+)


Download ppt "CS5205Haskell1 CS5205: Foundations in Programming Languages FP with Haskell A pure lazy functional language that embodies many innovative ideas in language."

Similar presentations


Ads by Google