【CS 61a Study notes1】- Higher-order function

Higher-order function

Def : A funtion returns a function or takes a function as an argument

Why higher-order function

High-order functions separate the functions into different parts to reduce the repetition

Higher-order func example

We wanna to get the inverse of the square function by using the search func

def search(f):
	x = 0
	while True:
		if f(x):
			return x 
		x += 1
		
def square(x):
	return x*x

def inverse(f):
	""" return g(y) such that g(f(x))=x """
	return lambda y : search(lambda x : f(x)==y)
		

The return part of the inverse function seems difficult to figure out , so now we can use nesting structure to rewrite it to make it clearer.


# ref: lambda function : lambda x : f(x)==y
def anonymous_func(x):
	return f(x)==y

# let's begin:
def inverse(f):
	def inverse_of_f(y):
		def is_inverse_of_y(x):
			return f(x)==y
		return search(is_inverse_of_y)
	return inverse_of_f
	

Self reference

When we use the self reference ,we must pay attention to the RecursionError.


def print_num(x):
	print(x)
	def next_sum(y):
		return print_num(x+y)
	return next_sum
	
>>> print_num(1)(3)(5)
1
4
9

We notice that finally it returns a function named next_sum. As long as we don’t give the y-value , it won’t continue.

Curry function

Curry function can help us change the strategt that we do not need to put all parameters at once.

def curry2(f):
	def g(x)
		def h(y)
			return f(x,y)
		return h
	return g

Using *arg

When we define a higher-order function ,but we are not sure about the number of parameters . At this time we can put *arg into the parameter position. *arg means you can give arbitraty number parameters to fit the function.

def printed(f):
	def print_and_return(*arg):
		res = f(*arg)
		print(res)
		return res
	return print_and_return

>>> test = printed(pow)
>>> test(2,3)
8
>>> def add_more(x,y,z,k):
...		return x+y+z+k
>>> test2 = printed(add_more)
>>> test2(1,2,3,4)
10

Repeat function example[fill in the blanks]

def repeat(k):
	""" >>>repeat(1)(7)(7)(2)(3)(1)(3)(1)
		7
		1
		3
		1
		return the nums we have seen before
	"""
	return __________(k)

def detector(f):
	def g(i):
		if _________:
			________
		return ______________
	return g
	

First, it is ease to know that the suite of if statement must be the print function. And the conditional part must be related with the f.
If we let f to be a check function ,we can find that the main check part must be displayed in the return of g function.
So the return part of g should be a self reference of detector func.
Now we need to figure out the return part of g function.
Then we need to know that if we want to create new variables without def statement in just one row ,we can use lambda function to implement.
We notice that the parameter of detector function is a function ,so we can consider using lambda function .
So the lambda function inside the detector function is the check function , which means whether it has seen i before .
But it is not enough, we are not only check the latest number , we need to check all the number that has occured ever before , so we need to call the exist function f again in the lambda function .
Finally , it comes to the repeat function. When we see the way of calling the repeat func, we can easily know that it must return a function and need to check whether the first number k has occured before.
So this function may be similar with the return part of g function .The difference is that we can make sure we haven’t seen the k before when k be the first number.
Now we can fill the blanks and check it.

def repeat(k):
	return detector( lambda j : False)(k)
	
def detector(f):
	def g(i):
		if f(i):
			print(i)
		return detector(lambda j : j==i or f(j))
	return g

If we want to make our code clearer , we can use the specific function name to represent f .

def repeat(k):
	return detector(lambda j : False)(k)
def detector(have_seen):
	def check(i):
		if have_seen(i):
			print(i):
		new_seen = lambda j : j==i or have_seen(j)
		return detector(new_seen)
	return check

In the following part , we can list the call steps to make it clearer.

>>>repeat(1)(7)(7)

have_seen0 = lambda j : False
have_seen1 = lambda j: j == 1 or have_seen0(j)
have_seen2 = lambda j: j == 7 or have_seen2(j)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值