引数xをとり、以前に同じ引数で関数が呼び出されたかどうかを調べる関数(see x)を実装しようとしています。例えばScheme:関数が同じ引数で呼び出されたかどうかをチェックする方法
: (begin (seen 5) (seen 10)) => #f
機能seen
は一個の引数を取るので、私は、以前と呼ばれる関数を取得する方法がわかりません。
引数xをとり、以前に同じ引数で関数が呼び出されたかどうかを調べる関数(see x)を実装しようとしています。例えばScheme:関数が同じ引数で呼び出されたかどうかをチェックする方法
: (begin (seen 5) (seen 10)) => #f
機能seen
は一個の引数を取るので、私は、以前と呼ばれる関数を取得する方法がわかりません。
以前の呼び出しを「記憶」する手順を記述する必要があります。 (グローバルな状態を回避するため)これは、可変状態を使用せずに行うことはできませんが、少なくとも、我々はプロシージャ内でそれをカプセル化することができます:
(define seen
(let ((already-seen (mutable-set)))
(lambda (n)
(cond ((set-member? already-seen n)
#t)
(else
(set-add! already-seen n)
#f)))))
トリックはすでに見た値を保存するためのデータ構造を定義することでしたの前に実際にlambda
を定義しています。 lambda
はその定義されたコンテキストで閉じるため、その状態にアクセスし、必要に応じて変更します。
メンバシップテストをサポートする任意のデータ構造(リスト、ハッシュ、名前)に、すでに見た値を格納することができます。しかし、set
はより自然であり、それが私が使用したものです。動作は期待通りです:
(seen 5)
=> #f
(seen 5)
=> #t
(seen 10)
=> #f
こんにちは、私が得るのは#procedureであり、ブール値ではありません。 –
それは私のために働く、多分あなたはそれを間違って呼び出している、あなたのコードを投稿してください。また、どの言語を使用していますか?それは教える言語の1つですか? –
もう一度試してみるとうまくいきます。しかし、とにかく私が議論をするための機能と見なすことができるかどうか疑問に思っていますか? –
単純な答えは "グローバル可変状態"ですが、通常は悪い考えであるため、私はそれを提供することを嫌いです。これは何のため? memoizationの実装に関する回答は、何らかの検索アルゴリズムを実装するものとは異なります。 –