2012-07-03 4 views
4

depuis hier, j'ai essayé de programmer une déclaration spéciale de cas pour le régime qui procédez comme suit:utilisation du système Définir syntaxe

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

au lieu d'utiliser tous les et de et la déclaration de cond, je serais:

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

ce que je pouvais le faire jusqu'à présent, était le suivant:

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

avec ce code:

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

Ce que je voulais faire maintenant, est tout simplement permettre la déclaration de Scase d'avoir plusieurs arguments comme ceci:

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

, mais je ne peux pas sembler comprendre comment je peux le faire. Peut-être que vous pourriez me donner un peu d'aide?

Merci à l'avance;)

Répondre

2

Si ceci est un exercice pour apprendre à utiliser les règles-syntaxe, puis ne pas tenir compte de cette réponse.

Je vois un moyen de simplifier votre code que vous démarrez.

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

Comme tout le (and (list? x) x) => (lambda l ... fait est si x est une liste, puis lier l-x, (puisque #f n'est pas une liste, et '() n'est pas faux, au moins Racket), vous pouvez juste passez tout cela et utilisez simplement x. Vous n'avez pas besoin d'utiliser => dans le cas, et dans ce cas, cela n'aide pas. => est utile si vous voulez faire un test qui retourne quelque chose d'utile en cas de succès, ou #f sinon. Maintenant, si vous voulez utiliser une macro, alors vous devrez clarifier ce que vous voulez faire un peu mieux. Je pense que cette affaire fait déjà ce que vous voulez. Votre macro existante est juste if, donc je ne suis pas sûr de savoir comment l'étendre.

2

J'ai trouvé la solution pour ma question, ici il va:

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

Merci à tous de toute façon :)

+0

Si cela répond à votre question, vous devriez [l'accepter] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). –

0

Voici une solution:

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

Il travaille en DrRacket. J'ai apporté trois modifications à votre solution. Premièrement, j'ai renommé votre procédure sort en sort1 puisque le tri est intégré dans le schéma (je l'ai utilisé à l'intérieur sort1). Deuxièmement, j'ai changé le sort1 lui-même de sorte que l'entrée donnée sera passée à la procédure retournée par scase et vous obtiendrez directement le résultat trié. Troisièmement, j'ai modifié l'extension de syntaxe scase, afin qu'elle accepte la condition else.

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

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

> (sort1 'here) 
"here" 

Je vous suggère de lire "Le langage de programmation Scheme" par Kent Dybvig.Il y a un chapitre entier sur les extensions syntaxiques.

+0

Err, tout ce que vous avez fait est ré-écrire cond (sans le => "caractéristique"). Le code fonctionne si vous remplacez scase par cond dans votre réponse finale. Si c'est ce que vous faites, dites-le. –

Questions connexes