1 / 50

CSE-321 Programming Languages Introduction to Functional Programming (Part II)

CSE-321 Programming Languages Introduction to Functional Programming (Part II). 박성우. POSTECH March 12, 2007. Outline. Expressions and values V Variables V Functions V Types Polymorphism Recursion Datatypes Pattern matching Higher-order functions Exceptions Modules. f.

molimo
Download Presentation

CSE-321 Programming Languages Introduction to Functional Programming (Part II)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CSE-321 Programming LanguagesIntroduction to Functional Programming(Part II) 박성우 POSTECH March 12, 2007

  2. Outline • Expressions and values V • Variables V • Functions V • Types • Polymorphism • Recursion • Datatypes • Pattern matching • Higher-order functions • Exceptions • Modules

  3. f fnf => (f true, f false) ( true, false) f f What is the Type of ? All we know about f is that it takes booleans as arguments.

  4. f All we know about f is that it takes booleans as arguments. bool ?

  5. f : bool -> ? fnf => (f true, f false) : (bool -> ?) -> ? * ?

  6. f : bool -> 'a • 'a • type variable • usually read as alpha • means 'for any type alpha' fnf => (f true, f false) : (bool -> 'a) -> 'a * 'a

  7. Polymorphic Types • Types involving type variables 'a, 'b, 'c, ... • E.g. • fnx => x : 'a -> 'a • fnx => fny => (x, y) : 'a -> 'b -> ('a * 'b) • fn (x : 'a) => fn (y : 'a) => x = y : 'a -> 'a -> bool (* actually does not typecheck! *)

  8. Equality Types • Motivation • Equality (=) is not defined on every type. • E.g. • comparing two functions for equality? • Type variables with equality • ''a, ''b, ''c, ... • ''a means 'for any type alpha for which equality is defined' • fn (x : ''a) => fn (y : ''a) => x = y : ''a -> ''a -> bool

  9. Outline • Expressions and values V • Variables V • Functions V • Types V • Recursion • Datatypes • Pattern matching • Higher-order functions • Exceptions • Modules

  10. Recursion in SML fun sum n =if n = 0 then 0else sum (n - 1) + n Iteration in C int i, sum; for (i = 0, sum = 0; i <= n; i++)sum += n; Recursion vs. Iteration • Recursion is not an awkward tool if you are used to functional programming. • Recursion seems elegant but inefficient!

  11. 0 + 1 1 + 2 36 + 9 f 1 f 8 f 9 f 0 45 + 10 55 Recursion in Action fun sum n =if n = 0then0else sum (n - 1) + n call stack 0 further computation ... ... f 10 evaluation

  12. 0 0 0 ... ... 0 f 0 f 8 f 1 f 9 0 f 10 0 Funny Recursion fun zero n =if n = 0then0else zero (n - 1) call stack no further computation evaluation

  13. 0 0 f 1 f 9 f 8 f 0 0 0 Funny Recursion Optimized fun zero n =if n = 0then0else zero (n - 1) call stack 0 0 ... ... f 10 evaluation

  14. f 9 f 8 f 1 f 0 Funny Recursion Further Optimized fun zero n =if n = 0then0else zero (n - 1) call stack f 10 ... 0 evaluation

  15. Tail Recursive Function • A tail recursive function f: • A recursive call to f is the last step in evaluating the function body. • That is, no more computation remains after calling f itself. • A tail recursive call needs no stack! • A tail recursive call is as efficient as iteration!

  16. Tail recursive sum fun sum' accum k =if k = 0 thenaccumelse sum' (accum + k) (k - 1) fun sum n = sum' 0 n Example • Non-tail recursive sum fun sum n =if n = 0 then 0else sum (n - 1) + n • Think about the invariant of sum: • given: sum' accum k • invariant: accum = n + (n - 1) + ... (k + 1)

  17. Outline • Expressions and values V • Variables V • Functions V • Types V • Recursion V • Datatypes • Pattern matching • Higher-order functions • Exceptions • Modules

  18. Enumeration Types in C enum shape { Circle, Rectangle, Triangle}; • Great flexibility • e.g. Circle + 1 == Rectangle Triangle - 1 == Rectangle (Circle + Triangle) / 2 == Rectangle • But is this good or bad?

  19. Datatypes in SML datatype shape = Circle | Rectangle | Triangle • No flexibility • e.g. Circle + 1 (x) Triangle - 1 (x) Circle + Triangle (x) • But high safety.

  20. Set datatype set = Empty | Many - Empty; val it = Empty : set - Many; val it = Many : set

  21. Set with Arguments datatype set = Empty | Many ofint - Many 5; val it = Many 5 : set

  22. Set with Type Parameters datatype'a set = Empty | Singleton of'a | Pair of'a * 'a - Singleton 0; val it = Singleton 0 : int set - Pair (0, 1); val it = Pair (0, 1) : int set

  23. Set with Type Parameters datatype'a set = Empty | Singleton of'a | Pair of'a * 'a - Pair (Singleton 0, Pair (0, 1)) val it = Pair (Singleton 0, Pair (0, 1)) : int set set

  24. Set with Type Parameters datatype'a set = Empty | Singleton of'a | Pair of'a * 'a - Pair (0, true); stdIn:27.1-27.15 Error: operator and operand don't agree [literal] operator domain: int * int operand: int * bool in expression: Pair (0,true)

  25. Recursive Set with Type Parameters datatype'aset = Empty | NonEmpty of'a * 'aset • This is essentially the definition of datatype list.

  26. Datatype list datatype'alist = nil | :: of'a * 'alist - nil; val it = [] : 'a list - 2 :: nil; (* :: infix *) val it = [2] : int list - 1 :: (2 :: nil); val it = [1,2] : int list - 1 :: 2 :: nil; (* :: right associative *) val it = [1,2] : int list

  27. Datatype list datatype 'a list = nil | :: of 'a * 'a list - 1 :: [2] :: nil; - [1] :: 2 :: nil; - [1] :: [2] :: nil; val it = [[1],[2]] : int list list - [1] :: [[2]]; val it = [[1],[2]] : int list list (X) (X)

  28. Using Datatypes • We know how to create values of various datatypes: • shape • set • int set • int list • ... • But how do we use them in programming? • What is the point of creating datatype values that are never used?

  29. Outline • Expressions and values V • Variables V • Functions V • Types V • Recursion V • Datatypes V • Pattern matching • Higher-order functions • Exceptions • Modules

  30. Simple Pattern datatype shape = Circle | Rectangle | Triangle (* convertToEnum : shape -> int *) fun convertToEnum (x : shape) : int = case x of Circle=> 0 |Rectangle=> 1 |Triangle=> 2

  31. Pattern with Arguments datatype set = Empty | Many ofint fun size (x : set) : int = case x of Empty => 0 | Many n => n

  32. Wildcard Pattern _ : "don't care" datatype 'a set = Empty | Singleton of 'a | Pair of 'a * 'a fun isEmpty (x : 'a set) : bool = case x of Empty => true | _ => false

  33. Pattern with Type Annotation datatype 'a list = nil | :: of 'a * 'a list fun length (x : 'a list) : int = case x of (nil : 'a list) => 0 | (_ : 'a) :: (tail : 'a list) => 1 + length tail

  34. Outline • Expressions and values V • Variables V • Functions V • Types V • Recursion V • Datatypes V • Pattern matching V • Higher-order functions • Exceptions • Modules

  35. Higher-order Functions • Take functions as arguments. • Return functions as the result.

  36. Why "Higher-order"? • T0 ::= int | bool | real | unit | ... • T1 ::= T0 -> T0 | T0 (* 1st order *) • T2 ::= T1 -> T1 | T1 (* 2nd order *) • T3 ::= T2 -> T2 | T2 (* higher order *) • ...

  37. Higher-order Functions in List • val exists : ('a -> bool) -> 'a list -> bool • val all : ('a -> bool) -> 'a list -> bool • val map : ('a -> 'b) -> 'a list -> 'b list • val filter : ('a -> bool) -> 'a list -> 'a list • val app : ('a -> unit) -> 'a list -> unit (* printInt : int -> unit *) fun printInt i = TextIO.print ((Int.toString i) ^ "\n" ); List.appprintInt[1, 2, 3];

  38. b2 b1 b3 bn bn-1 f f f f f List Fold Function • foldl : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b foldr : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b • foldl f b0 [a0, a1, a2, ..., an-1] a2 a0 a1 an-2 an-1 ... b0 ... bn-2

  39. + ¢ + + + ¢ + ¢ ¢ Summation fun sum (l : int list) = List.foldl (fn (a, accum) => a + accum) 0 l • foldl op+ 0 [a0, a1, a2, ..., an-1] op+ a2 a0 a1 an-2 an-1 ... 0 ... ¢

  40. List Reversal fun reverse (l : 'a list) = List.foldl (fn (a, rev) => a :: rev) nil l fun reverse (l : 'a list) = List.foldlop:: nil l • Whenever you need iterations over lists, first consider foldl and foldr.

  41. More Examples List.exists f l = List.foldl (fn (a, b) => b orelse f a) false l List.all f l = List.foldl (fn (a, b) => b andalso f a) true l List.app f l = List.foldl (fn (a, _) => f a) () l List.map f l = List.foldr (fn (a, b) => f a :: b) nil l List.filter f l = List.foldr (fn (a, b) => if f a then a :: b else b) nil l

  42. Outline • Expressions and values V • Variables V • Functions V • Types V • Recursion V • Datatypes V • Pattern matching V • Higher-order functions V • Exceptions • exception: please see the course notes. • Modules

  43. Outline • Expressions and values V • Variables V • Functions V • Types V • Recursion V • Datatypes V • Pattern matching V • Higher-order functions V • Exceptions V • Modules

  44. Structure collection of type declarations, exceptions, values, and so on. structure Set = struct type 'a set = 'a list val emptySet = nil fun singleton x = [x] fun union s1 s2 = s1 @ s2 end Signature conceptually type of structures. signature SET = sig type 'a set val emptySet : 'a set val singleton : 'a -> 'a set val union : 'a set -> 'a set -> 'a set end Structures and Signatures

  45. Transparent constraint Type definition is exported to the outside. structure Set : SET = struct type 'a set = 'a list val emptySet = nil fun singleton x = [x] fun union s1 s2 = s1 @ s2 end - Set.singleton 1 = [1]; val it = true : bool Opaque constraint No type definition is exported. structure Set :> SET = struct type 'a set = 'a list val emptySet = nil fun singleton x = [x] fun union s1 s2 = s1 @ s2 end - Set.singleton 1 = [1]; (* Error! *) Structures + Signatures

  46. We need to test your 46 structures! structure ahwbestOne :> HW_ONE = ... structure bopyOne :> HW_ONE = ... structure diozzOne :> HW_ONE = structure freeOne :> HW_ONE = ... ... structure zistinOne :> HW_ONE = ... • How can we test 46 structures? ) They all conform to the same signature. ) We use a functor!

  47. Functors • Functions on structures • takes a structure as an argument • returns a structure as the result structure structure

  48. HW1 Test Functor signature HW_TEST = sig val score : int end structure S = HwSolOne functor Hw1TestFn (P : HW_ONE val name : string) : HW_TEST = struct open P ... val sumScore = test "sum" 5 sumS.sum [1, 5, 10] val facScore = test "fac" 5 facS.fac [1, 5, 10 ] val gcdScore = test "gcd" 4 gcdS.gcd [(15,20), (24,12), (10000,0)] ... val cartprodScore = test "cartprod" 8 (cartprod [1,2,3])(S.cartprod [1,2,3]) [["a","b","c","d"]] val score = sumScore + facScore + ... + cardprodScore val _ = print ("\n " ^ name ^ ", score : " ^ (Int.toString score) ^ "\n" ) ... end

  49. HW1 Test Functor in Action structure ahwbestOneTest = Hw1TestFn (structure P = ahwbestOne val name = "ahwbest") structure bopyOneTest = Hw1TestFn (structure P = bopyOne val name = "bopy") structure diozzOneTest = Hw1TestFn (structure P = diozzOne val name = "diozz") structure freeOneTest = Hw1TestFn (structure P = freeOne val name = "free") ... structure zistinOneTest = Hw1TestFn (structure P = zistinOne val name = "zistin")

  50. So it is YOU who will grade your homework! Learn functors to find your score!

More Related