Exercise 1.41 ~ 1.44

1.41

定义一个 double 操作,用来将某个特定的操作重复两次。

例如我们有一个inc的操作会将某个数值加1,那么(double inc)则会将数值加二。

 

最终需要计算这个值:

 

写道
(((double (double double)) inc) 5)

 

下面是实现:

(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之后返回的方法,返回值仍然是一个方法。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值