Made case macro do more work
Now the case macro is closer to a pattern-matcher.
This commit is contained in:
parent
52ec79f61b
commit
2477fe9f4b
|
@ -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))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user