4

昨日以来、私は次のことを行うスキームの特別なケースステートメントをプログラムしようとしています:

(define (sort x)
  (cond ((and (list? x) x) => (lambda (l)
                                (sort-list l)))
        ((and (pair? x) x) => (lambda (p)
                        (if (> (car p) (cdr p))
                            (cons (cdr p) (car p))
                            p)))
        (else "here")))

すべての and と cond のステートメントを使用する代わりに、次のようにします。

(define (sort x)
  (scase ((list? x) => (lambda (l)
                                (sort-list l)))
         ((pair? x) => (lambda (p)
                        (if (> (car p) (cdr p))
                            (cons (cdr p) (car p))
                            p)))
        (else "here")))

私がこれまでにできたことは、これでした:

(define (sort x)
  (scase (list? x) (lambda (l)
                      (sort-list l)))
  (scase (pair? x) (lambda (p)
                        (if (> (car p) (cdr p))
                            (cons (cdr p) (car p))
                            p))))

このコードで:

(define-syntax scase
  (syntax-rules ()
    ((if condition body ...)
     (if condition
         (begin
           body ...)))))

私が今やりたかったことは、scase ステートメントが次のように複数の引数を持つことを許可することです。

(scase ((list? (cons 2 1)) 'here)
       ((list? '(2 1)) 'working))

しかし、どうすればそれができるのかわからないようです。多分あなたたちは私に少し助けを与えることができますか?

前もって感謝します ;)

4

3 に答える 3

2

これが構文規則の使用方法を学習する演習である場合は、この回答を無視してください。

あなたが始めようとしているコードを単純化する方法を見つけました。

(define (sort x)
  (cond ((list? x)
            (sort-list x))
        ((pair? x)
            (if (> (car x) (cdr x))
                (cons (cdr x) (car x))
                x)))
        (else "here")))

がリストである(and (list? x) x) => (lambda l ...かどうかを確認しx、 にバインドlするだけなxので (少なくとも Racket では は#fリストではなく、 false ではないため)、すべてをスキップして を使用するだけです。ケースで使用する必要はありません。この場合は役に立ちません。 成功した場合、またはそうでない場合に何か有用なものを返すテストを実行したい場合に便利です。'()x=>=>#f

さて、マクロを使用したい場合は、何をより良くしたいのかを明確にする必要があります。そのケースはすでにあなたが望むことをしていると思います。あなたの既存のマクロはただifなので、それを拡張する方法がわかりません。

于 2012-07-03T17:57:12.913 に答える
2

私は私の質問の解決策を見つけました。

(define-syntax cases
  (syntax-rules ()
    ((_ (e0 e1 e2 ...)) (if e0 (begin e1 e2 ...)))
    ((_  (e0 e1 e2 ...) c1 c2 ...)
     (if e0 (begin e1 e2 ...) (cases c1 c2 ...)))))

とにかくありがとうございました:)

于 2012-07-04T00:30:02.940 に答える
0

これが解決策です:

#lang racket

(require mzlib/defmacro)

(define-syntax scase
  (syntax-rules (else)
    ((_ (else body1)) body1)
    ((_ (condition1 body1) (condition2 body2) ...)
     (if condition1
         body1
         (scase (condition2 body2) ...)))))

(define (sort1 x)
  ((scase ((list? x) (lambda (l)
                      (sort l <)))
         ((pair? x) (lambda (p)
                      (if (> (car p) (cdr p))
                          (cons (cdr p) (car p))
                          p)))
         (else (lambda (e) "here")))
   x))

DrRacketで動作します。ソリューションに3つの変更を加えました。まず、sortがschemeに組み込まれているため、sortプロシージャの名前をに変更しました(内部で使用しました)。次に、指定された入力がによって返されるプロシージャに渡され、ソートされた結果が直接取得されるように、それ自体を変更しました。第三に、条件を受け入れるように構文拡張を変更しました。sort1sort1sort1scasescaseelse

>(sort1 (list 3 1 2))
'(1 2 3)

> (sort1 (cons 2 1))
'(1 . 2)

> (sort1 'here)
"here"

KentDybvigによる「TheSchemeProgrammingLanguage」を読むことをお勧めします。構文拡張に関する章全体があります。

于 2012-07-04T02:24:08.150 に答える