CS61A hw03
make_anoymous_factorial()
自问自答&写在前面
写这些是因为这道练习没写出来,刚开始看到官方的solution也没看明白,通过从答案反推之后,有了一些对lambda表达式的一些理解,在此分享,观看之前还是希望经过自己思考之后再看,毕竟聪明的你都来学cs61a了,应该已经学会独立思考的能力,参照题目,带着理解来看。鄙人也只是计算机小白,可能表达的不是很明白,如果有理解偏差请多多包涵。
-
如何不借助函数名实现递归: 通过额外传入一个函数变量f,通过f来实现递归
lambda f,n:1 if n==1 else mul(n,f(f,sub(n-1)))
此时该lambda表达式也可以改写为:
def λ(f,n): if n==1: return 1 else : return mul(n,f(f,sub(n-1)))
到这里产生了几个疑问:
- 什么是f函数
- 为什么f函数有两个参数
先回答第一个: 我们通过f实现递归,f的功能应该和示例中给出的fact函数功能完全相同,所以f函数相当于一个改写的fact函数
为什么有两个参数: 示例中fact函数就是lamda n:1 if n==1 else mul(n,fact(sub(n-1)))
函数本身,递归就是通过调用函数函数本身定义的,所以f函数与lambda表达式的参数保持一致
但到此时又产生了一个问题: 题目要通过调用make_anoymous_factorial()(n)
得到答案,按照上述的写法要调用make_anoymous_factorial()(f,n)
才能得到答案,并且这里产生了一个问题,既然我能传入一个全新的函数f,那我为什么不直接用fact函数呢
所以我们就要消去参数f,那么如何消去呢: 柯里化!!
只要通过以下最基础的方式就可以实现柯里化:
def λ1(f):
def λ2(x):
return f(f,x)
return λ2
通过这种方式就可以通过λ1(f)(x)
来代替f(f,x)
最后返回只需要通过返回λ1(f)
即可得到最终答案
在得到最终答案前我们要先对λ1函数
进行lambda表达式的改写:
lambda f:lambda x:f(f,x) #改写后的λ1函数
现在我们有了λ1函数
:lambda f:lambda x:f(f,x)
和柯里化第一个参数f函数
:lambda f,n:1 if n==1 else mul(n,f(f,sub(n-1)))
只要将两个带入λ1(f)
表达式即可得到答案:(lambda f: lambda k: f(f, k))(lambda f, k: k if k == 1 else mul(k, f(f, sub(k, 1))))
写在最后&一点碎碎念
应该没人会看吧,写了蛮多的相当于一篇小题解了,虽然没事高深的算法,以后的使用中也大概因为代码的可读性不会这么写递归函数,但不得不说对掌握lambda表达式大有脾益,只学到点皮毛真的很难做出来,可能也是因为我太菜了,如果有人能看到这里,并且产生了一定的帮助,我真的会很开心的,当然官方的solution中还有另一种解法,也可以自行尝试一下,当然这篇自问自答也只是写给自己的,可能有些地方没有那么详细,也请谅解