2012-07-03 3 views
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"))) 

вместо того, чтобы использовать все и-х и о 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)) 

, но я не могу понять, как я могу сделать это. Может быть, вы, ребята, могли бы мне немного помочь?

Заранее спасибо;)

ответ

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 не список, а '() не является ложным, по крайней мере, в рэкет), вы можете просто пропустите все это и просто используйте x. Вам не нужно использовать => в случае, и в этом случае это не поможет. => полезен, если вы хотите сделать тест, который возвращает что-то полезное, если оно выполнено успешно, или #f иначе.

Теперь, если вы хотите использовать макрос, вам нужно будет уточнить, что вы хотите, чтобы он немного улучшился. Я думаю, что этот случай уже делает то, что вы хотите. Ваш существующий макрос - это только if, поэтому я не уверен, как его расширить.

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 ...))))) 

Спасибо всем так или иначе :)

+0

Если это ответили на ваш вопрос, вы должны [принять его] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). –

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" 

Предлагаю вам прочитать «Язык программирования схемы» Кент Дыбвиг.Существует целая глава по синтаксическим расширениям.

+0

Err, все, что вы сделали, перезаписывает cond (без функции => "). Код работает, если вы замените scase на cond в своем окончательном ответе. Если это то, что вы делаете, просто скажите это. –

Смежные вопросы