sicp每日一题[2.84]

Exercise 2.84

Using the raise operation of Exercise 2.83, modify the apply-generic procedure so that it coerces its arguments to have the same type by the method of successive raising, as discussed in this section.
You will need to devise a way to test which of two types is higher in the tower. Do this in a manner that is “compatible” with the rest of the system and will not lead to problems in adding new levels to the tower.


这道题难度也不大,而且 tower 结构更简单,参考 2.81 和 2.83 再针对参数类型分别进行处理就行了

(define (apply-generic op . args) 
  (define (no-method type-tags) 
    (error "No method for these types" 
           (list op type-tags)))
  
  (define (type-tags args) 
    (map type-tag args))

  ; 将当前的类型升级为上一级,如果不存在对应的转换函数,返回 false
  (define (tower-raise origin target)
    (let ((o-type (type-tag origin))
          (t-type (type-tag target)))
      (cond ((eq? o-type t-type)
             origin)
            ((get 'raise (list o-type))
             (tower-raise ((get 'raise (list o-type)) (contents origin) target)))
            (else false))))

  (let ((proc (get op (type-tags args)))) 
    (if proc 
        (apply proc (map contents args))
        (if (= (length args) 2)
            ;; 假设类型以简单的 tower 形式排序,从低到高
            (let ((curr (car args))
                  (next (cadr args)))
              (cond ((eq? (type-tag curr) (type-tag next))
                     (no-method (type-tags args)))
                    ((tower-raise curr next)
                     (apply-generic op (tower-raise curr next) next))
                    ((tower-raise curr next)
                     (apply-generic op (tower-raise next curr) curr))
                    (else (no-method (type-tags args)))))
            (no-method (type-tags args))))))
posted @   再思即可  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示