我在Scheme中编写自动记忆器时遇到了一些问题。

我有一个有效的记忆功能,它创建一个哈希表并检查该值是否已经计算出来。如果之前已经计算过,则返回值,否则调用该函数。

(define (memoizer fun)
  (let ((a-table (make-hash)))
    (λ(n)
      (define false-if-fail (λ() #f))
      (let ((return-val (hash-ref a-table n false-if-fail)))
        (if return-val
            return-val
            (begin
              (hash-set! a-table n (fun n))
              (hash-ref a-table n)))))))

现在我想创建一个像这样的 memoize-wrapper 函数:

(define (memoize-wrapper function)
  (set! function (memoizer function)))

希望创建一个名为 def-memo 的宏,它用 memoize-wrapper 定义函数。例如。宏可以扩展为 (memoizer (define function-name argument body ...) 或类似的东西。

这样我应该能够做到:

(def-memo (factorial n)
  (cond
    ((= n 1) 1)
    (else (* n (factorial (- n 1))))))

它应该创建阶乘的记忆版本,而不是正常的慢速版本。

我的问题是

  1. memoize-wrapper 无法正常工作,它没有调用 memoized 函数,而是调用原始函数。
  2. 我不知道如何在宏内部编写定义。如何确保可以获得可变长度参数和可变长度主体?然后我如何定义该函数并将其与记忆器包裹起来?

多谢。

有帮助吗?

解决方案

这是我在 PLT 方案中使用的:

#lang scheme

(define (memo f)
  (define mh (make-hash))
  (lambda p
    (hash-ref mh p (lambda ()
                     (hash-set! mh p (apply f p))
                     (hash-ref mh p)))))

(define-syntax-rule (defmemo (id . p) . body)
  (define id (memo (lambda p . body))))

(provide defmemo)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top