CSED101 INTRODUCTION TO COMPUTING HIGH ORDER FUNCTION ( 고차함수 )
description
Transcript of CSED101 INTRODUCTION TO COMPUTING HIGH ORDER FUNCTION ( 고차함수 )
CSED101 INTRODUCTION TO COMPUTINGHIGH ORDER FUNCTION ( 고차함수 )
유환조Hwanjo Yu
Review: Fibonacci sequence
Fibonacci sequence ( 피보나치 수열 ) 1, 1, 2, 3, 5, 8, 13, 21, … Fn = Fn-1 + Fn-2 F2 = F1 = 1
–2
Review: Fibonacci sequence
Input and output type: int - > int Argument is assumed to be >= 1 fib n returns Fn in the fibonacci sequence let rec fib n =
if n > 2 then fib (n-1) + fib (n-2) else 1;;
Fib calls itself twice - fib (n-1) and fib (n-2), but the arguments will be decreased by one or two each time it is called, thus No infinite loop!
–3
Review: Recursive function with unchanging argument Q: what would be the output?
let k = 3;; let rec f n =
if n > 1 then k * (f (n-1) ) + 1 else 1;;
f 3;; In f, k is fixed
When f is defined, k=3. Thus, an = 3an + 1 If we want an=5an+1, then function f cannot be
used. How to let k be variable?
–4
Review: Recursive function with unchanging argument Define f_gen that has a variable k let f_gen k n =
if n > 1 then k * (f_gen k (n-1) ) + 1 else 1;;
You can call f_gen with a variable k, thus k is set at the time f is called rather than f is defined.
But, note that the value k is not changing when f_gen is called inside f_gen. Only the argument n is changing.
This is ok because k is not used in the terminal condition.
–5
Review: Recursive function having multiple outputs Example sequence
an = 2an-1 + bn-1 bn = an-1 + 2bn-1 a1 = p b1 = q
let rec f_pair n = If n > 1 then
Let (a, b) = f_pair (n-1) in (2*a + b, a + 2*b) Else
(p, q);;
–6
Review: Recursive function having multiple variable arguments
How to compute the GCD (Greatest Common Divisor) ( 최대공약수 ) of two values a and b? E.g., a=12 and 6=18, gcd is 6 Euclidean Algorithm: Keep subtracting smaller
value from larger value until two values become equal
Let rec gcd a b = If a > b then gcd (a-b) b Else if a < b then gcd a (b-a) Else a;;
–7
High order function First-order function
Functions that use basic types (e.g., int, float, string,..) as arguments or function output
All the functions we have seen so far are first-order functions
High-order function Functions that use functions as
arguments or function output
–8
High-order function Three types of high-order function
1. Use functions as arguments2. Use functions as outputs3. Use functions as both arguments and
outputs
–9
1. Function as argument E.g., let app_zero f = f 0;;
val app_zero : (int -> 'a) -> 'a = <fun> Why f has the type of int -> ‘a ? let inc x = x + 1;; let dec x = x - 1;; app_zero inc;; app_zero dec;;
–10
1. Function as argument # let app_twice_zero f = f (f 0);;
val app_twice_zero : (int -> int) -> int = <fun>
The argument is a function of (int -> int). Why?
The output is int. Why? app_twice_zero inc;; app_twice_zero dec;;
–11
1. Function as argument # let app_thrice_zero f = f (f (f 0));;
val app_thrice_zero : (int -> int) -> int = <fun>
# app_thrice_zero inc;; - : int = 3
# app_thrice_zero dec;; - : int = -3
–12
1. Function as argument # let rec app_times_zero f n =
if n = 0 then 0 else f (app_times_zero f (n - 1));; val app_times_zero : (int -> int) -> int -> int
= <fun> # app_times_zero inc 10;;
- : int = 10 # app_times_zero dec 10;;
- : int = -10
–13
2. Function as output # let incr_n n = fun x -> x + n;;
val incr_n : int -> int -> int = <fun> “int -> int -> int” is equivalent to “int ->
(int -> int)” # (incr_n 10) 0;;
- : int = 10 # (incr_n (-10)) 0;;
- : int = -10
–14
2. Function as output “# let inc = fun x -> x + 1;;”
is equivalent to “# let inc x = x + 1;;” # let incr_n’ n x = x + n;;
val incr n’ : int -> int -> int = <fun> incr_n’ and incr_n are equivalent! # incr_n 10 0;;
- : int = 10 # incr_n’ 10;;
- : int -> int = <fun>
–15
2. Function as output linear(x) = ax+b
let linear a b x = a * x + b;; let linear a b = fun x -> a * x + b;; let linear a = fun b x -> a * x + b;; let linear a = fun b -> fun x -> a * x + b;; let linear = fun a -> fun b -> fun x -> a * x +
b;; let linear = fun a b x -> a * x + b;;
T1 -> T2 -> … -> Tn-1 -> Tn is equivalent to T1 -> (T2 -> … -> (Tn-1 -> Tn) …)
–16
3. Function as argument and output h(x) = f(x) + g(x)
let combine f g = let h x = f x + g x in h let combine f g = fun x -> f x + g x
# let h = combine (fun x -> x + 1) (fun y -> y - 1) in h 0;; - : int = 0
# let combine f g = let h x = f x + g x in h;; val combine : ('a -> int) -> ('a -> int) -> 'a -> int =
<fun> # let combine2 f g = let h x = f x + g x in h 0;;
val combine2 : (int -> int) -> (int -> int) -> int = <fun>
–17
Type variable # let combine f g = fun x -> f x + g x;;
val combine : ('a -> int) -> ('a -> int) -> 'a -> int = <fun>
f and g’s argument has the same type since x is shared, but the type of x is undetermined.
f and g return values of int type since they are used as operands of “+”
Note: The type of x is determined not in compile time but in runtime or when the function is actually called. Why can’t it be determined in compile time?
–18
Type variable # let combine f g = fun x -> f x + g x;;
val combine : ('a -> int) -> ('a -> int) -> 'a -> int = <fun>
# combine (fun x -> x + 1) (fun y -> y - 1);; - : int -> int = <fun>
# combine (fun x -> if x then 1 else 0) (fun y -> if y then 0 else 1);; - : bool -> int = <fun> Fun x -> (fun k -> if k ….) x + (fun y -> …) x
–19
Type variable Polymorphic function
functions having type variables # let pair x y = (x, y);;
val pair : ’a -> ’b -> ’a * ’b = <fun> # pair 0 0;;
- : int * int = (0, 0) # pair 0 true;;
- : int * bool = (0, true)
–20