2009-06-30 10 views
5

私はSchemeにオートメモイザーを書く際にいくつかの問題に直面しています。Schemeにオートメモイザーを書く。マクロとラッパーのヘルプ

私は、ハッシュテーブルを作成し、その値がすでに計算されているかどうかをチェックする作業中のmemoizer関数を持っています。それが前に計算されていた場合は、関数を呼び出すelseを返します。

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

、うまくいけばmemoizeラッパーで関数を定義DEF、メモと呼ばれるマクロを作成:

(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-ラッパー関数を作成したいです。例えば。マクロは(memoizer(に展開することのように関数名引数本体...)か何かを定義することができ

をだから私は行うことができるはずということ:。のメモ化バージョンを作成する必要があり

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

代わりに、通常の遅い1の階乗。

私の問題は

  1. memoize-ラッパーが正しく動作していないということです、それはメモ化機能が、元の関数を呼び出すdoesntの。
  2. マクロ内に定義を書く方法がわかりません。どのように私は可変長引数と可変長ボディを得ることができることを確認するのですか?どのようにして関数を定義し、それをmemoizerでラップするのですか?

ありがとうございます。

答えて

6

これは私が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) 
+0

WOW。それはちょうど素晴らしいです。簡単にあなたのコード、特にマクロビットをコメントできますか?なぜそこにいるのですか? ?なぜあなたは提供しましたか?本当に申し込みが必要ですか?私は初心者です。ありがとう。 – unj2

+1

パラメータリストで、。次の変数が複数のものに束縛されていることを示します。マクロでは、pは単なるparamではなくparamsのリストです(bodyは式のリストです)。この関数の場合と同じことに、関数fにpのリストを適用するためにapplyが必要です。 –

+0

これも参照してください:http://planet.plt-scheme.org/display.ss?package=memoize.plt&owner=dherman –

関連する問題