5

「通常の」関数は通常、特定の型のオブジェクトのドメインでのみ定義されますが、Scheme の型述語list?やなどの特定の関数はprocedure?、任意の型の引数に対して定義され、それ自体に適用することもできます。したがって、たとえば(list? procedure?)は に評価され#f、 に(procedure? procedure?)評価され#tます。この種の完全に定義された関数を記述する方法を理解しようとしていますが、これについて議論している情報源を見つけることができませんでした。

たとえば、次のコンストラクタとセレクタを使用して、コンピューター プログラムの構造と解釈の演習 2.4 で説明されているペア データ型を実装するとします。

    (define (cons x y)
      (lambda (m) (m x y)))

    (define (car z)
      (z (lambda (p q) p)))

    (define (cdr z)
      (z (lambda (p q) q)))

を使用して構築されたものとそうでないものpair?を返す述語を定義するにはどうすればよいでしょうか。より一般的には、型の述語はどのように実装されていますか?#tcons#flist?procedure?

4

3 に答える 3

4

それは簡単だ。プロシージャを再定義して、作成するオブジェクトのタイプを最初の引数に設定します。

(define +type-pair+ 'pair)
(define +type-number+ 'number)

(define (cons a d)
  (lambda (m) (m +type-pair+ a d)))

(define (type x)
  (x (lambda (t . rest) t)))

(define (pair? c)
  (eq? (type c) +type-pair+))

(define (car c)
  (if (pair? c)
      (c (lambda (t a d) a))
  (error "Argument is not pair!")))

(define (cdr c)
  (if (pair? c)
      (c (lambda (t a d) d))
  (error "Argument is not pair!")))

(define (number? c)
   (if (type c) +type-number+))

これを使用して、プロシージャを含む言語のすべてを定義できますが、すべてが (type x) での型の指定をサポートする必要があり、何かを使用するすべてのプロシージャは型が正しいことを確認する必要があります。ペアをクロージャーとして実装するのはおそらく最も遅い方法なので、クロージャーとは何かを理解するための SICP 思考実験です。Arc はすべてのデータ型にタグを使用しますが、データをデータとして保持します。タグ付けがどのように機能するかを確認するには、Arc を確認する必要があります。

于 2012-08-06T12:51:29.820 に答える
3

ちなみに、Racketでは、structで作成された構造体述語がすでにこの作業を行っているため、手動で実装する必要はありません。

すべての専門家レベルのスキームは、構造またはレコードを介して同様の機能を提供します。SRFI-9を参照してください。これは、他の多くのScheme実装がすでに実行することを説明しています。

于 2012-08-06T22:58:06.773 に答える
1

あなたが示したコードではできませんでした。手順は不透明です。

1 つの可能性として、タグ付きリストを使用するようにコンストラクター/アクセサーを変更する必要があります。

(define *church-pair-tag* (list '*church-pair-tag*))

(define (cons x y)
   (cons *church-pair-tag* (lambda(m) (m x y))))

(define (church-pair? x)
   (and (pair? x) 
        (eq? *church-pair-tag* (car x))
        (procedure? (cdr x))))

....

しかし、それは明らかに絶対確実ではありません。

述語pair?およびprocedure?は組み込みであり、おそらく何らかの内部魔法によって実装されています。、null?、およびlist?の観点から実装できます。pair?carcdr

于 2012-08-05T22:50:34.300 に答える