Made case macro do more work

Now the case macro is closer to a pattern-matcher.
This commit is contained in:
William J. Bowman 2015-09-24 18:01:42 -04:00
parent 52ec79f61b
commit 2477fe9f4b
No known key found for this signature in database
GPG Key ID: DDD48D26958F0D1A
4 changed files with 23 additions and 22 deletions

View File

@ -83,7 +83,7 @@ defining curried functions via @racket[lambda*].
Like @racket[define], but uses @racket[forall*] instead of @racket[lambda*]. Like @racket[define], but uses @racket[forall*] instead of @racket[lambda*].
} }
@defform[(case* D e P [pattern maybe-IH body] ...) @defform[(case* e [pattern maybe-IH body] ...)
#:grammar #:grammar
[(pattern [(pattern
constructor constructor
@ -98,7 +98,7 @@ defined.
@examples[#:eval curnel-eval @examples[#:eval curnel-eval
(require cur/stdlib/nat) (require cur/stdlib/nat)
(case* Nat z (lambda (x : Nat) Bool) (case z
[z true] [z true]
[(s (n : Nat)) [(s (n : Nat))
IH: ((_ : Bool)) IH: ((_ : Bool))

View File

@ -6,13 +6,10 @@
(true : Bool) (true : Bool)
(false : Bool)) (false : Bool))
(define-syntax (if syn) (define-syntax-rule (if t s f)
(syntax-case syn () (case t
[(_ t s f) [true s]
;; Compute the motive [false f]))
(let ([M #`(lambda (x : #,(type-infer/syn #'t))
#,(type-infer/syn #'s))])
(quasisyntax/loc syn (elim Bool t #,M s f)))]))
(define (not (x : Bool)) (if x false true)) (define (not (x : Bool)) (if x false true))

View File

@ -15,16 +15,17 @@
(check-equal? (add1 (s z)) (s (s z)))) (check-equal? (add1 (s z)) (s (s z))))
(define (sub1 (n : Nat)) (define (sub1 (n : Nat))
(case* Nat n (lambda (x : Nat) Nat) (case n
[z z] [z z]
[(s (x : Nat)) IH: ((ih-n : Nat)) x])) [(s (x : Nat)) IH: ((ih-n : Nat)) x]))
(module+ test (module+ test
(check-equal? (sub1 (s z)) z)) (check-equal? (sub1 (s z)) z))
(define (plus (n1 : Nat) (n2 : Nat)) (define (plus (n1 : Nat) (n2 : Nat))
(case* Nat n1 (lambda (x : Nat) Nat) (case n1
[z n2] [z n2]
[(s (x : Nat)) IH: ((ih-n1 : Nat)) [(s (x : Nat))
IH: ((ih-n1 : Nat))
(s ih-n1)])) (s ih-n1)]))
(module+ test (module+ test
(check-equal? (plus z z) z) (check-equal? (plus z z) z)

View File

@ -6,12 +6,8 @@
lambda* lambda*
#%app #%app
define define
case* case
define-type define-type)
define-theorem
qed
real-app
define-rec)
(require (require
(only-in "../cur.rkt" (only-in "../cur.rkt"
@ -79,10 +75,17 @@
;; TODO: Expects clauses in same order as constructors as specified when ;; TODO: Expects clauses in same order as constructors as specified when
;; TODO: inductive D is defined. ;; TODO: inductive D is defined.
(define-syntax (case* syn) (define-syntax (case syn)
(syntax-case syn () ;; duplicated code
[(_ D e P clause* ...) (define (clause-body syn)
#`(elim D e P #,@(map rewrite-clause (syntax->list #'(clause* ...))))])) (syntax-case (car (syntax->list syn)) (: IH:)
[((con (a : A) ...) IH: ((x : t) ...) body) #'body]
[(e body) #'body]))
(syntax-case syn (=>)
[(_ e clause* ...)
(let* ([D (type-infer/syn #'e)]
[M (type-infer/syn (clause-body #'(clause* ...)))])
#`(elim #,D e (lambda (x : #,D) #,M) #,@(map rewrite-clause (syntax->list #'(clause* ...)))))]))
(define-syntax-rule (define-theorem name prop) (define-syntax-rule (define-theorem name prop)
(define name prop)) (define name prop))