[Buggy] Partially fixed match on type familes.

Fixed various application syntax bugs in match.

Match still fails to infer the correct motive on type familes.
This is due to indices being instantiated differently between motive and
match clause.
This commit is contained in:
William J. Bowman 2016-01-17 17:31:33 -05:00
parent 09f47481ab
commit b52dca0114
No known key found for this signature in database
GPG Key ID: DDD48D26958F0D1A
2 changed files with 48 additions and 15 deletions

View File

@ -14,8 +14,16 @@
(nil : (-> (A : Type) (List A))) (nil : (-> (A : Type) (List A)))
(cons : (-> (A : Type) A (List A) (List A)))) (cons : (-> (A : Type) A (List A) (List A))))
(define list-ref (define (list-ref (A : Type) (ls : (List A)))
(elim (match ls
[nil (lambda (n : Nat) (none A))]
[(cons (A : Type) (a : A) (rest : (List A)))
(lambda (n : Nat)
(match n
[z (some A a)]
[(s (n-1 : Nat))
((recur rest) n-1)]))])
#;(elim
List List
Type Type
(lambda (A : Type) (ls : (List A)) (lambda (A : Type) (ls : (List A))

View File

@ -44,7 +44,7 @@
(pattern (pattern
type:expr type:expr
#:attr name (format-id #'type "~a" (gensym))))) #:attr name (format-id #'type "~a" (gensym 'anon-parameter)))))
;; A multi-arity function type; takes parameter declaration of either ;; A multi-arity function type; takes parameter declaration of either
;; a binding (name : type), or type whose name is generated. ;; a binding (name : type), or type whose name is generated.
@ -96,6 +96,10 @@
[(_ e1 e2 e3 ...) [(_ e1 e2 e3 ...)
(quasisyntax/loc syn (quasisyntax/loc syn
(#%app (#%app e1 e2) e3 ...))])) (#%app (#%app e1 e2) e3 ...))]))
(module+ test
((lambda (A : (Type 1)) (B : (Type 1)) A)
Type
Type))
(define-syntax define-type (define-syntax define-type
(syntax-rules () (syntax-rules ()
@ -157,28 +161,39 @@
#:attr indices #:attr indices
'() '()
#:attr decls #:attr decls
(list #`(#,(gensym) : x))) (list #`(#,(gensym 'anon-discriminant) : x)))
(pattern (pattern
(x:id e:expr ...) ;; For some reason app is made explicit here
((~optional (~literal real-app)) x:id e:expr ...+)
#:attr inductive-name #:attr inductive-name
#'x #'x
#:attr indices #:attr indices
(attribute e) (attribute e)
#:attr names #:attr names
(for/list ([e (attribute e)]) (for/list ([e (attribute e)])
(format-id e "~a" (gensym))) (format-id e "~a" (gensym 'anon-index)))
#:attr types #:attr types
;; TODO: Detect failure, report error/suggestions ;; TODO: Detect failure, report error/suggestions
(for/list ([e (attribute e)]) (for/list ([e (attribute e)])
(type-infer/syn e)) (or (type-infer/syn e)
(raise-syntax-error
'match
(format
"Could not infer type of index ~a"
e)
e)))
#:attr decls #:attr decls
(append (append
(for/list ([name (attribute names)] (for/list ([name (attribute names)]
[type (attribute types)]) [type (attribute types)]
#`(name : type)) [src (attribute e)])
(quasisyntax/loc src
(#,name : #,type)))
;; TODO: quasisyntax/loc ;; TODO: quasisyntax/loc
(list #`(#,(gensym) : ((x e ...) #,@(attribute names))))))) (list
(quasisyntax/loc #'x
(#,(gensym 'anon-discriminant) : (x #,@(attribute names))))))))
;; todo: Support just names, inferring types ;; todo: Support just names, inferring types
(define-syntax-class match-declaration (define-syntax-class match-declaration
@ -202,7 +217,7 @@
'()) '())
(pattern (pattern
(x:id d:match-declaration ...) (x:id d:match-declaration ...+)
#:attr local-env #:attr local-env
(for/fold ([d (make-immutable-hash)]) (for/fold ([d (make-immutable-hash)])
([name (attribute d.name)] ([name (attribute d.name)]
@ -224,11 +239,13 @@
(for/fold ([decls (attribute d.decls)]) (for/fold ([decls (attribute d.decls)])
([type-syn (attribute d.types)] ([type-syn (attribute d.types)]
[name-syn (attribute d.names)] [name-syn (attribute d.names)]
[src (attribute d.decls)]
;; NB: Non-hygenic ;; NB: Non-hygenic
;; BUG TODO: This fails when D is an inductive applied to arguments...
#:when (cur-equal? type-syn D)) #:when (cur-equal? type-syn D))
(let ([ih-name (quasisyntax/loc d #,(format-id name-syn "ih-~a" name-syn))] (define/syntax-parse type:inductive-type-declaration type-syn)
;; BUG TODO: This is broken; motive must be applied to indices and such, too (let ([ih-name (quasisyntax/loc src #,(format-id name-syn "ih-~a" name-syn))]
[ih-type #`(#,motive #,name-syn)]) [ih-type #`(#,motive #,@(attribute type.indices) #,name-syn)])
(dict-set! ih-dict (syntax->datum name-syn) ih-name) (dict-set! ih-dict (syntax->datum name-syn) ih-name)
(append decls (list #`(#,ih-name : #,ih-type))))))) (append decls (list #`(#,ih-name : #,ih-type)))))))
@ -289,11 +306,19 @@
'match 'match
"Could not infer return type. Try using #:return to declare it." "Could not infer return type. Try using #:return to declare it."
syn))) syn)))
;; BUG TODO: return-type is inferred with the indexes of the branches, but those must be abstracted in the motive...
(~bind (motive (quasisyntax/loc syn (~bind (motive (quasisyntax/loc syn
(lambda #,@(attribute D.decls) return-type)))) (lambda #,@(attribute D.decls) return-type))))
(~var c (match-clause (attribute D) (attribute motive))) ...) (~var c (match-clause (attribute D) (attribute motive))) ...)
(quasisyntax/loc syn (quasisyntax/loc syn
(elim D.inductive-name #,(type-infer/syn (attribute return-type)) (elim
D.inductive-name
#,(or
(type-infer/syn (attribute return-type))
(raise-syntax-error
'match
"Could not infer type of motive. Sorry, you'll have to use elim."
syn))
motive motive
c.method ... c.method ...
#,@(attribute D.indices) #,@(attribute D.indices)