1

だからここに私の問題があります(抽象的な状況に一般化されています)。一般的には通訳です。

入力リストを解析する必要があるプログラムを取得し、その要素に従って、変数を変更する必要があるいくつかの関数を順次呼び出します。関数は個別に定義され、(condによって選択されます。更新する必要があるこれらの 3 つの変数には、現在の状況 (正確には、ロボットの位置、迷路、およびロボットの向き) に関する情報が含まれています。前の関数の結果は、次の関数で使用されます (つまり、更新された変数が使用されます)。

(define func-a ... )
(define func-b ... )

(define (main-func <maze> <orientation> <coordinates> <list with commands>)

  ;; here I parse the list and choose which function to call
  ;; output must contain (list <new-maze> <new-orientation> <new-coordinates>))

)

これらの変数を更新するには、どのスキーム ツールを使用できますか? 私はいくつかのオプションを検討しました:

  • use (define してから set を呼び出します! (純粋な関数型プログラミングではないため、これは悪いスタイルです);
  • 関数を最初から最後まで呼び出します (これは機能しません。移動が有効かどうかも確認する必要があります)。
  • これらの変数をまったく定数にしないでください。各関数に引数として渡してみてください。

他に適切な方法はありますか?

4

2 に答える 2

1

いくつかの状態を維持する(およびファイルを読み取る)必要があるため、純粋関数型プログラミングは存在せず、いくつかの逸脱を受け入れる必要があります。

一般的なアプローチは、共有オブジェクトをいくつかのメタ関数でローカルとして保持し、たとえば、parseなどの関数を呼び出して更新することです。parse-oneparse-two

今、あなたはそれらを更新する方法が必要です。

スコープ内でそれらを定義することによりparse-one、それらを表示することができます。parse-two

(let ((state (make-state)))
  (let ((parse-one (lambda () ...))
        (parse-two (lambda () ...)))
    ....))

または、戻り値を使用します。

(let ((state (make-state)))
  ...
  (set! state (parse-one state))
  ...)

OOPと呼ばれる3番目のアプローチがあります。それらすべてを単一のクロージャーで定義して、いくつかのデータを共有できるようにします。

(define (make-parser)
  (let ((state (make-state))
    (let (((parse-one (lambda () ...))
          ((parse-two (lambda () ...))
          ((get-state (lambda () state)))
       (list parse-one parse-two get-state))))

(destructuring-bind (parse-one parse-two get-state) (make-parser)
  ...
  (parse-one)
  ...
  (get-state))

destructuring-bindは、リストを破棄する簡単な方法です。スキームの実装を参照してください)しかし、最初のバージョンは複雑なバージョンのようです。

于 2013-03-10T18:06:21.127 に答える
1

Scheme が「関数型言語」と見なされているからといって、「set!」の使用を禁止しているわけではありません。・やっぱり使う言語にある。したがって、次のことに問題はありません。

(define-record-type position (fields x y z))

(define robot-position (make-position 0.0 0.0 0.0))

(define update-robot-position (new-x new-y new-z)
  (set! robot-position (make-position new-x new-y new-x)))

[位置を不変として定義することにしました。]

必要に応じて別のアプローチを選択することもできますが、基本的にロボットの位置が変更され、その変更がコードに何らかの形で反映されます。最も単純で簡単なアプローチを使用してみませんか?

于 2013-03-10T17:59:43.460 に答える