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's和cond's语句,我会:

(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-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 回答
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是一个列表,然后绑定lx, (因为#f不是一个列表,并且'()不是假的,至少在 Racket 中),你可以跳过所有这些并使用x. 你不需要使用=>in case,在这种情况下它没有帮助。 =>如果您想进行测试以在成功或其他情况下返回有用的东西,这很有用#f

现在,如果您想使用宏,那么您将需要澄清您希望它做得更好的事情。我认为那个案例已经做了你想要的。您现有的宏只是if,所以我不确定如何扩展它。

于 2012-07-03T17:57:12.913 回答
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。我对您的解决方案进行了三处更改。首先,我将您的sort程序重命名为,sort1因为 sort 是内置在方案中(我在里面使用过sort1)。其次,我已经改变了sort1它本身,以便将给定的输入传递给返回的过程scase,您将直接得到排序结果。第三,我修改了scase语法扩展,使其接受else条件。

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

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

> (sort1 'here)
"here"

我建议你阅读 Kent Dybvig 的“The Scheme Programming Language”。有一整章是关于语法扩展的。

于 2012-07-04T02:24:08.150 回答