定义语法方案用法

时间:2012-07-03 16:15:22

标签: lisp scheme

从昨天起,我一直在尝试为计划编写一个特殊的案例陈述,该陈述将执行以下操作:

(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")))

而不是使用所有的和和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))

但我似乎无法弄明白我该怎么做。也许你们可以给我一点帮助?

提前致谢;)

3 个答案:

答案 0 :(得分: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,(因为#f不是列表,'()并非虚假,至少在Racket中,你可以跳过所有这些并只使用x。您无需使用=>以防万一,在这种情况下它无济于事。如果您想要执行一项测试,以便在成功时返回有用的内容,或=>,则#f非常有用。

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

答案 1 :(得分: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 ...)))))
无论如何,谢谢大家:)

答案 2 :(得分: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,因为排序是在方案中构建的(我在sort1中使用过)。其次,我已经更改了sort1本身,以便将给定的输入传递给scase返回的过程,您将直接获得排序结果。第三,我修改了scase语法扩展,以便它接受else条件。

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

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

> (sort1 'here)
"here"

我建议您阅读Kent Dybvig撰写的“计划编程语言”。有一整章关于句法扩展。