2016-04-19 37 views
0

私はスキームの一般的なメモ処理手順を作るために宿題を割り当てられていますが、1つの引数を取るプロシージャでは動作しますが、1より大きい場合には最後の引数であると思われます。また、引数を取らない手続きをメモしても失敗します。一般的なメモのスキーム

ご協力いただければ幸いです。

(define mem 
    (lambda (mem-it func) 
    (let ((table (make-table))(func-store func)) 
     (cond 
     ((equal? mem-it 'memoize)   
     (lambda args 
      (if (null? args) 
       func 
       (let ((prev (lookup args table))) 
       (or prev 
        (let ((result (apply func args))) 
         (insert! args result table) 
         result)))))) 

     ((equal? mem-it 'unmemoize) 
     (func-store)) 

     (else (display "No Such command")))))) 

これは私がこれまでに

(define (test-proc . args) 
    (display "computing test-proc of ") 
    (display args) 
    (newline) 
    (if (null? args) 
     0 
     (+ (expt (- 42 (car args)) 2) 
     (apply test-proc (cdr args))))) 

そして、ここでのテスト手順は

が提供されてきた私は、次の試験に

(set! test-proc (mem 'memoize test-proc)) 
(test-proc 40 41 42 43 44) 
を実行しようとすると、エラーが発生したものです

他の手順はこちら

(define (make-table) 
    (list '*table*)) 

    (define (lookup key table) 
    (let ((record (assoc key (cdr table)))) 
     (and record (cdr record)))) 

(define (insert! key value table) 
    (let ((record (assoc key (cdr table)))) 
    (if record 
     (set-cdr! record value) 
     (set-cdr! table 
        (cons (cons key value) (cdr table)))))) 
+1

インデントがオフであるため、コードを読み取ることができません。なぜあなたのためにこれを行うエディタを使用しないでください? – Sylwester

+0

うまくいけば今より良く見える – Cezar

+0

あなたの問題は何ですか?あなたは複数の引数の関数をメモしようとしているのですか、または1つの引数のメモされた関数を値のリストに適用しようとしていますか? –

答えて

1

あなたmemoizarion手続きは引数が渡​​されていないときには、実施手順を返す機能を持っています

((mem 'memoize test-proc)) ; ==> test-proc 

テスト手順の基本ケースが(test-proc 1)ためのでこの機能により、あなたを打つことは決してありませんtest-procは数字ではないため、エラーを通知する式(+ 1681 test-proc)で置き換えることができます。

これは、ユニークな魔法値使用することをお勧めします:我々はそれがだリストを作っているので

(define +GET-PROC+ (list "get-proc")) 
(test-proc +GET-PROC+) ; ==> original-test-proc 

eq?そのデータのみです。 R6RSでは、エクスポートを控えることができるので、メモ帳を使用するコードは本当にそれを使いこなすことができません。例えば("get-proc")のようなすべてのリストはeq?にならないので、元の手順を取らずに引数として使うことができます。

(rnrs hashtables)またはSRFI-69の標準ハッシュ手順を使用していないので、チェックすることはできませんが、リストをキーとして使用しているので、ハッシュテーブルはequal?をテストとして使用する必要があります。ほとんどのリスプでハッシュテーブルを使用すると、これはしばしば欲求不満の原因になります。

+0

あなたが尋ねた手順を追加しました。助けてくれることを願っています。 – Cezar

+0

@Cezar 'assoc'は本当に' equal? 'を使っていますが、私の答えで述べたハッシュテーブルの実装よりも遅くなります。したがって、君が持つ唯一の問題は、あなたが魔法の価値として引数を使用しないことと、あなたがメモしようとしている手続きも引数を基本事例として使用しないことです。 – Sylwester