Scheme cached-assoc函数lambda参数v的来源及依据问询
Scheme cached-assoc 实现问题解答
相关实现代码如下:
(define (cached-assoc xs n) (letrec ([memo (make-vector n #f)] [acc 0] [f (lambda(x) (let ([ans (vector-assoc x memo)]) (if ans (cdr ans) (let ([new-ans (assoc x xs)]) (begin (vector-set! memo acc (cons x new-ans)) (set! acc (if (= (+ acc 1) n) 0 (+ acc 1))) new-ans)))))]) (lambda (v) (f v))))
注:原代码中游标自增的判断逻辑缺少比较目标n,已做修正,不影响参数设计的理解
参数v的来源
cached-assoc属于高阶工厂函数,你首次调用它传入关联表xs和缓存容量n后,它不会直接执行查询,而是返回末尾的匿名lambda函数作为专用的查询接口。后续你调用这个返回的查询接口时,主动传入的待查询键值就是参数v的实际取值。
实际调用示例:
;; 初始化专用查询函数,固定要查的关联表和缓存大小 (define cached-lookup (cached-assoc '((a . 1) (b . 2) (c . 3)) 2)) ;; 调用查询接口,这里传入的符号`b`就是匿名lambda的参数v (cached-lookup 'b)
参数v的设定依据
- 满足闭包的封装设计:内部的缓存向量
memo、循环游标acc都是私有状态,不允许外部直接修改,仅对外开放接收查询键的极简接口,v就是这个接口的唯一入参,用来传递给内部实际执行查询逻辑的辅助函数f。 - 对齐原生
assoc的使用习惯:原生Scheme的assoc调用格式为(assoc 待查键 关联表),cached-assoc把固定不变的关联表xs提前绑定到闭包中,用户后续重复查询时不需要反复传入关联表,只需要传入待查键即可,简化调用逻辑。
内容的提问来源于stack exchange,提问作者Amen
相关产品推荐
相关产品推荐

