1.41
定义一个 double 操作,用来将某个特定的操作重复两次。
例如我们有一个inc的操作会将某个数值加1,那么(double inc)则会将数值加二。
最终需要计算这个值:
下面是实现:
(defun db (f) (lambda (x) (funcall f (funcall f x)) ) ) (format t "~a~%" (funcall (funcall (db (db #'db)) #'(lambda (x) (+ x 1))) 5))
在我这里,运行的结果是21.
1.42
编写一个 compose 方法,它接收两个方法f、g,然后返回一个新的方法,这个方法对参数x,返回值 f(g(x)).
实现的方法比较简单,只需要依次调用两个方法就可以了。
(defun inc (x) (+ x 1)) (defun squar (x) (* x x)) (defun compose (f g) (lambda (x) (funcall f (funcall g x)))) (format t "~a~%" (funcall (compose #'squar #'inc) 6))
1.43
在平时的使用场景中,我们经常需要将一个函数的返回值,做为它自身的输入。比如,对函数f(x), 经常需要求值: f(f(...f(x)...)). 所以应该可以写一个方法repeated,他接受两个参数,一个函数f和一个计数n,返回的方法对给定的参数x,会执行n次函数f。 了解这些啰嗦的描述后,写起来倒是很简单。这里正好用到了1.42的compose函数。让f=g,compose方法相当于将函数f repeat了两次。
#1.43 (defun repeated (f count) (if (< count 2) (lambda (x) (funcall f x)) (compose f (repeated f (- count 1))) ) ) (format t "~a~%" (funcall (repeated #'squar 2) 5))
1.44
为了需要smoothing一个函数,对于x,需要求值(f(x) + f(x-dx) + f(x+dx))/3.我们需要编写一个方法,他的参数是一个函数,返回值是smoothing之后的函数。
(defun smooth (f) (let ((dx 1.0)) (lambda (x) (/ (+ (funcall f (- x dx)) (funcall f x) (funcall f (+ x dx))) 3.0))) ) (format t "~a~%" (funcall (smooth #'squar) 5))
如果你想对某个函数smoothing n次,就可以使用前面的repeat方法了:
(defun nth-smooth (f n) (lambda (x) (funcall (funcall (repeated #'smooth n) f) x) ) ) (format t "~a~%" (funcall (nth-smooth #'squar 2) 5))
因为我们重复的时“smooth”这个操作,所以首先对smooth方法执行 repeated操作n次,然后将f传值给前面返回的方法,就得到了我们想要的nth-smooth方法了。
这里跟前面两个题目不同的一点是,前面repeated之后的得到的方法,会返回一个值;这里repeated之后返回的方法,返回值仍然是一个方法。